webentwicklung-frage-antwort-db.com.de

iOS11 UIToolBar Inhaltsansicht

In iOS 11 Reagieren Schaltflächen und Textfelder nicht auf Unteransichten von UIToolBar. Wenn Sie die Ansichtshierarchie mit iOS 10 Vergleichen, sehen Sie, dass es über alle Unteransichten von UIToolBar einen _UIToolBarContentView Gibt.

Zum Beispiel bricht dieses neue Layout von UIToolBarslacktextviewcontrollerhttps://github.com/slackhq/SlackTextViewController/issues/604

Benötigen Sie eine Lösung in iOS 10/11.

32
Mustard

Um das Problem für iOS11 (Kompatibel mit früheren Versionen) zu lösen, müssen Sie nur layoutSubview erstellen, nachdem UIToolBar als Unteransicht zur Benutzeroberflächenhierarchie hinzugefügt wurde.

In diesem Fall wechselt _UIToolbarContentView Zur ersten Unteransicht von UIToolBar und Sie können alle Unteransichten höher als zuvor hinzufügen.

Zum Beispiel in ObjC,

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

    <here one can add all subviews needed>

Das gleiche Problem tritt mit slacktextviewcontroller auf

31
malex

Ich habe dieses Problem in meinem Fall gelöst. Ich schreibe die layoutSubviews -Methode in der Unterklasse von UIToobar um und ändere die userInteractionEnable von _UIToolbarContentView in 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;
         }
     }

}
3

Sie können einfach die hitTest(_:with:) -Methode verwenden.

  1. Erstellen Sie zunächst eine Eigenschaft contentView in UIToolbar:

    open private(set) var contentView: UIView = UIView()
    
  2. Stellen Sie dann den Rahmen des contentView auf den gleichen Wert wie den des UIToolbar. Beispielsweise:

    contentView.frame = bounds
    contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    addSubview(contentView)
    
  3. Überschreiben Sie abschließend die hitTest(_:with:) -Methode:

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

Wenn Sie in dieser Situation eine Symbolleiste anpassen möchten, indem Sie einfach zusätzliche Ansichten hinzufügen, sollten Sie fügen Sie sie zum contentView hinz, damit sie entsprechend positioniert werden.

1
hengyu

Das neue UIToolbar -Objekt verwendet das Layout aktiv basierend auf Einschränkungen. Daher ist es besser, die - (void)updateConstraints -Methode zu überschreiben. Um benutzerdefinierte Ansichten über UIToolbar -Objekte darzustellen, ist es besser, diese Unterklassen zuzuweisen und eine benutzerdefinierte Containeransicht hinzuzufügen:

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

Jetzt können Sie Ihre benutzerdefinierten Ansichten sicher zur Containeransicht hinzufügen. Damit die benutzerdefinierten Ansichten reagieren, müssen wir die Reihenfolge der Symbolleisten-Unteransichten nach der Aktualisierung der Einschränkungen ändern:

- (void)updateConstraints
{
    [super updateConstraints];

    [self bringSubviewToFront:self.containerView];
}

Wenn Sie UINavigationController mit der benutzerdefinierten Symbolleiste verwenden, müssen Sie erzwingen, dass das Layout aktualisiert wird, bevor Sie Ihre benutzerdefinierten Unteransichten hinzufügen.

0
voromax