UIToolBarの左右のパディングを調整する方法

iphone objective-c
UIToolBarの左右のパディングを調整する方法

1つのUIToolbarをコードで作成し、別のUIToolbarをインターフェイスビルダーで作成します。 しかし、以下に示すように、左右のパディングが異なる2つのツールバーが見つかりました。

Interface Builderから:

image:https://i.stack.imgur.com/sthpU.png [ここに画像の説明を入力]

コードから:

image:https://i.stack.imgur.com/gaN9u.png [ここに画像の説明を入力]

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];

私の質問は、コードによってUIToolbarの左右のパディングをどのように調整できますか?

更新

この整列の問題は、UIButtonのcustomViewを使用したUIBarButtonItemでのみ発生することがわかりました。UIBarButtonItemの場合、整列は正常です。 これを引き起こしたり、これを解決したりするアイデア。

私が今考えることができる唯一の解決策は、フレームを手動で設定することです。

  57  37


ベストアンサー

私は同じ問題を抱えていましたが、UIBarButtonSystemItemFixedSpaceでできる巧妙なトリックがあり、最初のボタンの前と最後のボタンの後に負の幅を持つこれらの1つを追加すると、ボタンが端に移動します。

たとえば、右側の余白を取り除くには、次のFixedSpaceバー項目を最後の項目として追加します。

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

左右のマージンは12pxです。

iOS7の更新-マージンはiPhoneでは16ピクセル、iPadでは20ピクセルです!

148


iOS 11より前

次の3つの解決策がありました。

  • 最初はスペースアイテムを修正して使用していました
    負の幅のUIBarButtonItem(barButtonSystemItem:.fixedSpace…)

  • もう1つは、カスタムビューでalignmentRectInsetsをオーバーライドすることでした

  • 最後の1つは、アイテムのカスタムビューとしてUIButtonを使用する場合です。
    contentEdgeInsetsとhitTest(_:with :)をオーバーライドします

絶対に、最初の解決策は他の解決策よりも優れているようです

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

swiftを使用すると、コードは次のようになります

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

iOS 11以降(iOS 11を含む)

残念ながら、すべてのソリューションをiOS 11で使用することはできません

  • 最初の解決策:負の幅の設定は機能しなくなりました

  • 2番目の解決策:alignmentRectInsetsをオーバーライドすると、アイテムの一部が発生します
    タッチを受け取らなくなりました

  • 最後の解決策:hitTest(_:with :)をオーバーライドするのは良くないと思います
    考えてください、これをしないでください!

https://forums.developer.apple.com/thread/80075 [開発者フォーラム]にもいくつかの提案がありますが、すべてのコメントを確認した後、このトピックに関する提案はカスタムUINavigationBarサブクラスを作成することです。何か複雑なことをします。

なんてこった、ナビゲーションバーではなく、パディングを変更するだけです!

幸いなことに、iOS 11ではこれをトリックを使って行うことができます!

さあ行こう:

1. カスタムボタンを作成する

  • translatesAutoresizingMaskIntoConstraintsをfalseに設定します

  • alignmentRectInsetsをオーバーライドします

  • 右側のアイテムはUIEdgeInsetsを使用します(上:0、左:-8、下:0、
    右:8)

  • 左側のアイテムはUIEdgeInsetsを使用します(上:0、左:8、下:0、右:
    -8)
    _
    alignmentRectInsetsがわからない場合は、最初に* https://useyourloaf.com/blog/auto-layout-and-alignment-rectangles/ [このブログ] *を読むことができます
    _

迅速なバージョン

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;

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;

2. カスタムボタンでアイテムを作成する

迅速なバージョン

var item = UIBarButtonItem(customView: customButton)

Objective-Cバージョン

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

3. *正*幅のfixedSpace型UIBarButtonItemを作成します

負の値ではなく、*正の*値を設定します

迅速なバージョン

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

Objective-Cバージョン

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

4. 配列をleftitemsまたはrightitemsに設定します

fixedSpaceタイプのUIBarButtonアイテムは、配列の*最初の要素*でなければなりません。

迅速なバージョン

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

Objective-Cバージョン

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

よくやった

すべての手順を実行すると、パディングが小さくなり、入力エリアが正しいように見えます。

何か間違ったことを見つけたら、私に知らせてください! あなたの質問に答えるために最善を尽くします!

Note

iOS 11より前は、デバイスの画面幅に注意する必要があります。画面が5.5インチの場合、マイナスは-12 pt、他の画面では-8ptです。

iOS 11で私のソリューションを使用する場合、デバイス画面を気にする必要はなく、8ptを設定するだけです、ナビゲーションバー、左側または右側のアイテムの位置を気にする必要があり、これはカスタムビューのalignmentRectInsetsに影響します

タップエリアを増やしたい

タップ領域が44 * 44より大きいことを約束する場合は、以下のメソッドをオーバーライドできます

- (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


これは素晴らしい質問であり、提供されているソリューションを使用しても、iOS11の問題は解決しませんでした。

ワーキングソリューション

`UIButton`の新しい拡張機能を作成する場合:

class BarButton: UIButton {

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

}

次に、レイアウトで使用する場合:

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
}()

問題がある場合、これは非常に迷惑な問題を解決しました。

6


このボタンを使用してください

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

3


私は同じ問題に出会った。 最後に、UIToolbarをサブクラス化してレイアウトサブビューメソッドをオーバーライドすることでこれを解決しました。

- (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


customview(initWithCustomView)を使用する場合は、ツールバーのオフセットと幅を変更できます

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

2


UIButtonのサブビューとしてツールバーを中央に配置しようとしたときに、私はこれにつまずきました。 ツールバーの幅を小さくする必要があるため、最良の解決策は、両側にある柔軟なボタンでした。

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


最後に、UIBarButtonItemの背景画像をカスタマイズし、配置を調整するために、UIBarButtonItemを放棄し、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];

0


トリッキーな方法は、アスペクト(またはメソッドのスウィズル)を使用することだと思います。

[UINavigationBar aspect_hookSelector:@selector(layoutSubviews) withOptions:AspectPositionAfter usingBlock:^(id 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


タイトルとURLをコピーしました