it-swarm.com.de

So passen Sie die linke und rechte Füllung von UIToolBar an

Ich erstelle eine UIToolbar mit Code und eine andere mit Interface Builder. Aber herausgefunden, dass die beiden Symbolleisten unterschiedliche linke und rechte Polsterung haben, wie unten gezeigt:

Vom Interface Builder:

enter image description here

Von Code:

enter image description here

UIImage *buttonImage = [[UIImage imageNamed:@"button.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0];
UIButton *btnTest = [UIButton buttonWithType:UIButtonTypeCustom];
[btnTest setBackgroundImage:buttonImage forState:UIControlStateNormal];
[btnTest setTitle:@"Back" forState:UIControlStateNormal];   
[btnTest.titleLabel setFont:[UIFont boldSystemFontOfSize:13]];  
[btnTest setBackgroundImage:[imgToolbarButton stretchableImageWithLeftCapWidth:5 topCapHeight:0]  forState:UIControlStateNormal];
[btnTest addTarget:self action:@selector(clearDateEdit:) forControlEvents:UIControlEventTouchUpInside];
btnTest.frame = CGRectMake(0.0, 0.0, 50, 30);
UIBarButtonItem *btnTestItem = [[UIBarButtonItem alloc] initWithCustomView:btnTest];
[self.toolbar setItems:[NSArray arrayWithObjects:btnTestItem,nil]];
[btnTestItem release];

Meine Frage ist, wie ich den linken und rechten Abstand der UIToolbar per Code einstellen kann.

Update

Ich habe festgestellt, dass dieses Ausrichtungsproblem nur bei UIBarButtonItem mit customView von UIButton passiert ist. Jede Idee, was das bewirkt oder dieses Problem lösen.

Die einzige Lösung, die mir jetzt einfällt, ist das manuelle Einstellen des Rahmens.

57
TonyTakeshi

Ich hatte das gleiche Problem, und es gibt einen hübschen Trick, den Sie mit einem UIBarButtonSystemItemFixedSpace ausführen können. Fügen Sie einen dieser mit einer negativen Breite vor dem ersten Button und nach dem letzten Button hinzu, und der Button wird zum Edge verschoben.

Um beispielsweise den rechten Rand loszuwerden, fügen Sie als letztes Element das folgende FixedSpace-Leistenelement hinzu:

UIBarButtonItem *negativeSeparator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
negativeSeparator.width = -12;

Die Ränder links und rechts betragen 12px.

Update für iOS7 - Die Margen betragen 16px auf dem iPhone und 20px auf dem iPad!

148
Craig Mellon

Vor iOS 11

Sie hatten drei mögliche Lösungen:

  • Beim ersten wurde ein Leerzeichenelement UIBarButtonItem (barButtonSystemItem: .fixedSpace…) mit einer negativen Breite festgelegt
  • Die andere bestand darin, alignRectInsets in der benutzerdefinierten Ansicht überschreiben
  • Wenn Sie UIButton als benutzerdefinierte Ansicht Ihres Elements verwenden, können Sie contentEdgeInsets überschreiben und auf Test (_: with :) klicken.

Absolut scheint die erste Lösung besser als die andere zu sein

UIBarButtonItem *negativeSeparator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
negativeSeparator.width = -12;

wenn Sie Swift verwenden, wird der Code so aussehen

var negativeSeparator = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
negativeSeparator.width = -12

Nach iOS 11 (enthalten iOS 11)

leider kann die gesamte Lösung nicht in iOS 11 verwendet werden 

  • erste Lösung: Das Einstellen einer negativen Breite funktioniert nicht mehr
  • zweite Lösung: Durch das Überschreiben von alignRectInsets werden Teile des Elements nicht mehr berührt
  • die letzte Lösung: Ich denke, überschreiben hitTest (_: with :) ist keine gute Idee, bitte nicht!

Sie können auch einen Vorschlag in den Developer Forums sehen, aber nachdem Sie den gesamten Kommentar durchgesehen haben, werden Sie zu diesem Thema einen Vorschlag finden, eine benutzerdefinierte UINavigationBar-Unterklasse zu erstellen und etwas Komplexität zu erreichen.

Oh mein Gott, ich möchte nur die Polsterung ändern, nicht die Navigationsleiste! 

Glücklicherweise können wir dies mit einem Trick in iOS 11 tun!

Auf geht's:

1. Erstellen Sie eine benutzerdefinierte Schaltfläche

  • set setzt translateAutoresizingMaskIntoConstraints als false
  • Überschreiben Sie alignRectInsets
    • element auf der rechten Seite verwende UIEdgeInsets (oben: 0, links: -8, unten: 0, rechts: 8)
    • element auf der linken Seite verwenden Sie UIEdgeInsets (oben: 0, links: 8, unten: 0, rechts: -8)

      wenn Sie AusrichtungRectInsets nicht kennen, können Sie zuerst dieses Blog lesen

Schnelle Version

var customButton = UIButton(type: .custom)
customButton.overrideAlignmentRectInsets = UIEdgeInsets(top: 0, left: x, bottom: 0, right: -x) // you should do this in your own custom class
customButton.translatesAutoresizingMaskIntoConstraints = false;

ziel-c-Version

UIButton *customButton = [UIButton buttonWithType:UIButtonTypeCustom];
customButton.overrideAlignmentRectInsets = UIEdgeInsetsMake(0, x, 0, -x); // you should do this in your own custom class
customButton.translatesAutoresizingMaskIntoConstraints = NO;

2. Erstellen Sie einen Artikel mit Ihrer benutzerdefinierten Schaltfläche

Schnelle Version

var item = UIBarButtonItem(customView: customButton)

ziel-c-Version

UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:customButton]

3. Erstellen Sie einen UIBarButtonItem-Typ mit festgelegtem Abstand mit der Breite positive

setzen Sie einen positiven - Wert und keinen negativen Wert

Schnelle Version

var positiveSeparator = UIBarButtonItem(barButtonSystemItem:.fixedSpace, target: nil, action: nil)
positiveSeparator.width = 8

ziel-c-Version

UIBarButtonItem *positiveSeparator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
positiveSeparator.width = 8;

4. Legen Sie ein Array auf Leftitems oder Rightitems fest

das UIBarButton-Element des fixedSpace-Typs muss das first-Element im Array sein.

Schnelle Version

self.navigationItem.leftBarButtonItems = [positiveSeparator, item, ...]

ziel-c-Version

self.navigationItem.leftBarButtonItems = @{positiveSeparator, item, ...}

Gut gemacht

nachdem Sie alle Schritte ausgeführt haben, werden Sie feststellen, dass Ihre Polsterung kleiner wird und der Textbereich richtig erscheint.

Wenn Sie etwas falsch finden, lassen Sie es mich wissen! Ich werde mein Bestes geben, um Ihre Frage zu beantworten!

Hinweis

Vor iOS 11 sollten Sie sich um die Bildschirmbreite des Geräts kümmern. Wenn der Bildschirm 5,5 Zoll ist, ist das Negativ -12 pt, auf anderen Bildschirmen ist -8pt.

Wenn Sie meine Lösung unter iOS 11 verwenden, brauchen Sie sich nicht um den Bildschirm des Geräts zu kümmern, setzen Sie einfach 8pt, Sie sollten die Position des Elements in der Navigationsleiste, auf der linken Seite oder auf der rechten Seite beachten. Dies wirkt sich auf Ihre benutzerdefinierte Ansicht aus alignRectInsets

Willst du mehr Tap-Bereich

Wenn Sie versprechen möchten, dass Ihr Tap-Bereich größer als 44 * 44 ist, können Sie die unten beschriebene Methode überschreiben

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    CGSize acturalSize = self.frame.size;
    CGSize minimumSize = kBarButtonMinimumTapAreaSize;
    CGFloat verticalMargin = acturalSize.height - minimumSize.height >= 0 ? 0 : ((minimumSize.height - acturalSize.height ) / 2);
    CGFloat horizontalMargin = acturalSize.width - minimumSize.width >= 0 ? 0 : ((minimumSize.width - acturalSize.width ) / 2);
    CGRect newArea = CGRectMake(self.bounds.Origin.x - horizontalMargin, self.bounds.Origin.y - verticalMargin, self.bounds.size.width + 2 * horizontalMargin, self.bounds.size.height + 2 * verticalMargin);
    return CGRectContainsPoint(newArea, point);
}
19
SketchK

Dies ist eine großartige Frage und auch bei den angebotenen Lösungen - das Problem wurde unter iOS11 nicht gelöst.

ARBEITSLÖSUNG

Wenn Sie eine neue Erweiterung von UIButton erstellen:

class BarButton: UIButton {

    override var alignmentRectInsets: UIEdgeInsets {
        return UIEdgeInsetsMake(0, 16, 0, 16)
    }

}

Wenn Sie es dann in Ihrem Layout verwenden:

lazy var btnLogin: BarButton = {
    let btn = BarButton(type: .custom)
    // Add your button settings

    btn.widthAnchor.constraint(equalToConstant: self.frame.size.width).isActive = true
    btn.heightAnchor.constraint(equalToConstant: 50).isActive = true
    btn.translatesAutoresizingMaskIntoConstraints = false
    return btn
}()

Dies löste ein sehr ärgerliches Problem, wenn Sie irgendwelche Probleme haben, rufen Sie mich an.

6
RichAppz

verwenden Sie diese Schaltfläche

UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                                                                           target:nil
                                                                           action:nil];
3
Madhu

Sie können den Versatz und die Breite Ihrer Symbolleiste ändern, wenn Sie customview (initWithCustomView) verwenden möchten. 

[myToolBar setFrame:CGRectMake(-10, 0, [UIScreen mainScreen].bounds.size.width+10, 44)];
2
Mihriban Minaz

Ich bin darauf gestoßen, als ich versuchte, eine Symbolleiste als Unteransicht eines UIButton zu zentrieren. Da die Symbolleiste eine geringe Breite haben musste, war die beste Lösung auf jeder Seite eine flexible Schaltfläche: 

UIBarButtonItem flexibleButtonItemLeft = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

UIBarButtonItem centeredButtonItem = ...

UIBarButtonItem flexibleButtonItemRight = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];

UIToolbar toolbar = ...

toolbar.items = @[flexibleButtonItemLeft, centeredButtonItem, flexibleButtonItemRight];
2
Karmeye

Ich habe das gleiche Problem getroffen. Zum Schluss habe ich das Problem gelöst, indem ich UIToolbar subclassing und die Methode für das Layout-Subviews überschreibe. 

- (void)layoutSubviews {

  [super layoutSubviews];

  if (leftItem_ && leftItem_.customView
      && [leftItem_.customView isKindOfClass:[UIButton class]]) {
    CGRect newFrame = leftItem_.customView.frame;
    newFrame.Origin.x = 0;   // reset the original point x to 0; default is 12, wired number
    leftItem_.customView.frame = newFrame;    
  }

  if (rightItem_ && rightItem_.customView
      && [rightItem_.customView isKindOfClass:[UIButton class]]) {
    CGRect newFrame = rightItem_.customView.frame;
    newFrame.Origin.x = self.frame.size.width - CGRectGetWidth(newFrame);
    rightItem_.customView.frame = newFrame;
  }

}
2
Fourj

Ich denke, ein kniffliger Weg ist, Aspekte (oder Methoden-Schwindel) zu verwenden, wie geblasen:

[UINavigationBar aspect_hookSelector:@selector(layoutSubviews) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info){
        UINavigationBar *bar = info.instance;

        //[bar layoutSubviews];

        if ([bar isKindOfClass:[UINavigationBar class]]) {
            if (@available(iOS 11, *)) {
                bar.layoutMargins = UIEdgeInsetsZero;

                for (UIView *subview in bar.subviews) {
                    if ([NSStringFromClass([subview class]) containsString:@"ContentView"]) {
                        UIEdgeInsets oEdges = subview.layoutMargins;
                        subview.layoutMargins = UIEdgeInsetsMake(0, 0, 0, oEdges.right);
                    }
                }
            }
        }
    } error:nil];
0
ekingo Hu

Einfach negative Konstanten hinzufügen zu führende und nachfolgende Bedingungen des UIToolbar. Auf diese Weise beginnt und endet die Symbolleiste außerhalb Ihrer Ansicht und ist daher weniger gepolstert.

0
fl034

Um das Hintergrundbild für UIBarButtonItem angepasst und die Ausrichtung angepasst zu haben, habe ich UIBarButtonItem aufgegeben und UIButton manuell hinzugefügt.

UIImage *buttonImage = [[UIImage imageNamed:@"button.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0];
UIButton *btnTest = [UIButton buttonWithType:UIButtonTypeCustom];
[btnTest setBackgroundImage:buttonImage forState:UIControlStateNormal];
[btnTest setTitle:@"Back" forState:UIControlStateNormal];   
[btnTest.titleLabel setFont:[UIFont boldSystemFontOfSize:13]];  
[btnTest setBackgroundImage:[imgToolbarButton stretchableImageWithLeftCapWidth:5 topCapHeight:0]  forState:UIControlStateNormal];
[btnTest addTarget:self action:@selector(clearDateEdit:) forControlEvents:UIControlEventTouchUpInside];
btnTest.frame = CGRectMake(0.0, 0.0, 50, 30);
[self.toolbar addSubview:btnTest];
[btnTestItem release];
0
TonyTakeshi