iOS 11
では、ボタンとテキストフィールドはUIToolBar
のサブビューであるため応答しません。ビュー階層をiOS 10
と比較すると、UIToolBar
のすべてのサブビューに_UIToolBarContentView
があります。
たとえば、UIToolBar
のこの新しいレイアウトはslacktextviewcontroller
を壊します https://github.com/slackhq/SlackTextViewController/issues/604
iOS 10/11
で動作するソリューションが必要です。
iOS11
(下位バージョンとの互換性)の問題を解決するには、UI階層のサブビューとしてlayoutSubview
を追加した直後にUIToolBar
を作成するだけです。
この場合、_UIToolbarContentView
はUIToolBarの最初のサブビューに下がり、すべてのサブビューを以前のように上に追加できます。
たとえば、ObjC
では、
UIToolbar *toolbar = [UIToolbar new];
[self addSubview: toolbar];
[toolbar layoutIfNeeded];
<here one can add all subviews needed>
slacktextviewcontroller でも同じ問題が発生します
私の場合、この問題を解決しました。 UIToobarのサブクラスのlayoutSubviews
メソッドを書き換え、_UIToolbarContentView
のuserInteractionEnable
を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:)
メソッドを使用するだけです。
まず、contentView
にプロパティUIToolbar
を作成します。
_open private(set) var contentView: UIView = UIView()
_
次に、contentView
のフレームをUIToolbar
のフレームと同じにします。例えば:
_contentView.frame = bounds
contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(contentView)
_
最後に、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
を使用している場合、カスタムサブビューを追加する前に、レイアウトを強制的に更新する必要があることに注意してください。