簡體   English   中英

iOS11 UIToolBar 內容視圖

[英]iOS11 UIToolBar Contentview

iOS 11按鈕和文本字段作為UIToolBar子視圖沒有響應。 將視圖層次結構與iOS 10進行比較,我們看到_UIToolBarContentView的所有子視圖上UIToolBar一個UIToolBar

例如, UIToolBar這個新布局打破了slacktextviewcontroller https://github.com/slackhq/SlackTextViewController/issues/604

需要一個適用於iOS 10/11的解決方案。

為了解決iOS11 (兼容低版本)的問題,你只需要在UIToolBar作為子視圖添加到UI層次結構后UIToolBar制作layoutSubview

在這種情況下_UIToolbarContentView降低到_UIToolbarContentView的第一個子視圖,您可以像以前一樣將所有子視圖添加到更高的位置。

例如在ObjC

    UIToolbar *toolbar = [UIToolbar new];
    [self addSubview: toolbar];
    [toolbar layoutIfNeeded];

    <here one can add all subviews needed>

slacktextviewcontroller 也會出現同樣的問題

我已經解決了這個問題。 我在 UIToobar 的子類中重寫了layoutSubviews方法,並將 _UIToolbarContentView 的userInteractionEnable _UIToolbarContentView為 NO。

- (void)layoutSubviews {
    [super layoutSubviews];


    NSArray *subViewArray = [self subviews];

    for (id view in subViewArray) {
        if ([view isKindOfClass:(NSClassFromString(@"_UIToolbarContentView"))]) {
            UIView *testView = view;
            testView.userInteractionEnabled = NO;
         }
     }

}

您可以只使用hitTest(_:with:)方法。

  1. 首先,在UIToolbar創建一個屬性contentView

     open private(set) var contentView: UIView = UIView()
  2. 然后,使contentView的框架與UIToolbar的框架相同。 例如:

     contentView.frame = bounds contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight] addSubview(contentView)
  3. 最后,覆蓋hitTest(_:with:)方法:

     open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { if self.point(inside: point, with: event) { if let hitTestView = contentView.hitTest(point, with: event) { return hitTestView } else { return self } } else { return nil } }

在這種情況下,如果您想通過簡單地添加其他視圖來自定義工具欄,您應該將它們添加到contentView以便它們被適當地定位。

新的UIToolbar對象主動使用基於約束的布局,所以最好重寫- (void)updateConstraints方法。 要在UIToolbar對象上顯示自定義視圖,最好將其子類化並添加自定義容器視圖:

- (UIView *)containerView
{
    if (_containerView) {
        return _containerView;
    }
    _containerView = [[UIView alloc] initWithFrame:self.bounds];
    _containerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    return _containerView;
}

現在您可以安全地將自定義視圖添加到容器視圖中。 為了使自定義視圖具有響應性,我們需要在約束更新后更改工具欄子視圖的順序:

- (void)updateConstraints
{
    [super updateConstraints];

    [self bringSubviewToFront:self.containerView];
}

請注意,如果您將UINavigationController與自定義工具欄一起使用,則應在添加自定義子視圖之前強制它更新其布局。

在僅具有自動布局和代碼的 Swift 中,對我有用的是在添加項目之前但在設置約束之后按照malex提到的方式進行布局。

  • 實例化你的工具欄
  • 將其添加到您的視圖中
  • 添加約束

    工具欄.layoutIfNeeded()

    工具欄.setItems([... (你的物品)], 動畫: 真)

有一種奇怪的方法可以做到這一點。

[self.textInputbar sendSubviewToBack:[self.textInputbar.subviews lastObject]];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM