Je crée un UIToolbar avec du code et un autre avec le constructeur d'interface. Mais, découvrez les deux barres d’outils avec un rembourrage différent à gauche et à droite, illustrées ci-dessous:
De Interface Builder:
De code:
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];
Ma question est comment puis-je ajuster le remplissage gauche et à droite de UIToolbar par code?
Mettre à jour
J'ai découvert que ce problème d'alignement ne concernait que UIBarButtonItem avec customView of UIButton. L'alignement est correct avec UIBarButtonItem. Toute idée de ce qui cause ceci ou pour résoudre ceci.
La seule solution à laquelle je puisse penser maintenant est de définir manuellement le cadre.
J'ai eu le même problème, et il y a une astuce que vous pouvez faire avec un UIBarButtonSystemItemFixedSpace, ajoutez un de ceux-ci avec une largeur négative avant votre premier bouton et après votre dernier bouton et cela déplacera le bouton vers Edge.
Par exemple, pour supprimer la marge de droite, ajoutez l'élément de barre FixedSpace suivant au dernier élément:
UIBarButtonItem *negativeSeparator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
negativeSeparator.width = -12;
Les marges à gauche et à droite sont 12px.
Mise à jour pour iOS7 - les marges sont de 16 pixels sur iPhone et de 20 pixels sur iPad!
Vous avez eu trois solutions possibles:
Absolument, la première solution semble meilleure que les autres
UIBarButtonItem *negativeSeparator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
negativeSeparator.width = -12;
si vous utilisez Swift, le code ressemblera à ceci
var negativeSeparator = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
negativeSeparator.width = -12
malheureusement, toute la solution ne peut pas être utilisée dans iOS 11
Vous pouvez également voir quelques suggestions sur les forums de développeurs , mais après avoir consulté tous les commentaires, vous trouverez une suggestion à ce sujet: créer une sous-classe UINavigationBar personnalisée et faire quelque chose de complexe.
Oh mon dieu, tout ce que je veux, c'est changer le rembourrage, pas la barre de navigation!
Heureusement, nous pouvons le faire avec une astuce dans iOS 11!
si vous ne connaissez pas alignmentRectInsets, vous pouvez lire CE BLOG en premier
Version rapide
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;
version objective-c
UIButton *customButton = [UIButton buttonWithType:UIButtonTypeCustom];
customButton.overrideAlignmentRectInsets = UIEdgeInsetsMake(0, x, 0, -x); // you should do this in your own custom class
customButton.translatesAutoresizingMaskIntoConstraints = NO;
Version rapide
var item = UIBarButtonItem(customView: customButton)
version objective-c
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:customButton]
définir une valeur positive et non une valeur négative
Version rapide
var positiveSeparator = UIBarButtonItem(barButtonSystemItem:.fixedSpace, target: nil, action: nil)
positiveSeparator.width = 8
version objective-c
UIBarButtonItem *positiveSeparator = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
positiveSeparator.width = 8;
fixedSpace type L'élément UIBarButton doit être le premier élément du tableau.
Version rapide
self.navigationItem.leftBarButtonItems = [positiveSeparator, item, ...]
version objective-c
self.navigationItem.leftBarButtonItems = @{positiveSeparator, item, ...}
après avoir suivi toutes les étapes, vous constaterez que votre rembourrage devient plus petit et que la zone de frappe semble correcte!
Si vous trouvez quelque chose qui ne va pas, s'il vous plaît faites le moi savoir! Je ferai de mon mieux pour répondre à votre question!
Avant iOS 11, vous devriez vous préoccuper de la largeur de l'écran de l'appareil. si l'écran est de 5,5 pouces, le négatif est de -12 points, sur les autres écrans de -8 points.
Si vous utilisez ma solution sur iOS 11, vous n'avez pas besoin de vous soucier de l'écran du périphérique, définissez simplement 8 pt, Vous devez vous soucier de la position de l'élément dans la barre de navigation, à gauche ou à droite, cela affectera votre vue personnalisée. alignementRectInsets
Si vous souhaitez promettre que votre zone de prise est supérieure à 44 * 44, vous pouvez remplacer la méthode ci-dessous.
- (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);
}
C'est une excellente question et même avec les solutions fournies - cela n'a pas résolu le problème sur iOS11.
SOLUTION DE TRAVAIL
Si vous créez une nouvelle extension de UIButton
:
class BarButton: UIButton {
override var alignmentRectInsets: UIEdgeInsets {
return UIEdgeInsetsMake(0, 16, 0, 16)
}
}
Ensuite, lorsque vous l'utilisez dans votre mise en page:
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
}()
Cela a résolu un problème très ennuyant, si vous avez des problèmes, faites-le moi savoir.
utiliser ce bouton
UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
Vous pouvez modifier le décalage et la largeur de votre barre d’outils si vous voulez utiliser customview (initWithCustomView).
[myToolBar setFrame:CGRectMake(-10, 0, [UIScreen mainScreen].bounds.size.width+10, 44)];
Je suis tombé sur cela en essayant de centrer une barre d'outils comme une sous-vue d'un UIButton. Comme la barre d’outils devait être de faible largeur, la meilleure solution consistait en un bouton flexible de chaque côté:
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];
J'ai rencontré le même problème. Enfin, j'ai résolu ce problème en sous-classant UIToolbar et en remplaçant la méthode de présentation des sous-vues.
- (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;
}
}
Je pense qu'un moyen délicat consiste à utiliser Aspects (ou méthode swizzling), comme indiqué
[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];
Juste ajoutez des constantes négatives à votre contraintes de début et de fin de la UIToolbar
. De cette façon, la barre d'outils commence et se termine en dehors de votre vue et a donc moins de remplissage.
Enfin, pour avoir personnalisé l’image d’arrière-plan de UIBarButtonItem et permettre l’alignement, j’ai abandonné UIBarButtonItem et ajouté manuellement UIButton.
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];