bottom - ios toolbar
iOS11 UIToolBar Contentview (5)
En iOS 11 botones y el campo de texto no responden como subvistas de UIToolBar . Al comparar la jerarquía de vistas con iOS 10 vemos que hay una _UIToolBarContentView sobre toda la subvista de UIToolBar .
Por ejemplo, este nuevo diseño de la UIToolBar rompe slacktextviewcontroller https://github.com/slackhq/SlackTextViewController/issues/604
Necesita una solución que funcione en iOS 10/11 .
El nuevo objeto UIToolbar utiliza activamente el diseño en función de las restricciones, por lo que es mejor anular el método - (void)updateConstraints . Para presentar vistas personalizadas sobre el objeto UIToolbar , es mejor UIToolbar una subclase y agregar una vista personalizada de contenedor:
- (UIView *)containerView
{
if (_containerView) {
return _containerView;
}
_containerView = [[UIView alloc] initWithFrame:self.bounds];
_containerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
return _containerView;
}
Ahora puede agregar de manera segura sus vistas personalizadas a la vista de contenedor. Para que las vistas personalizadas respondan, necesitamos cambiar el orden de las subvistas de la barra de herramientas después de la actualización de las restricciones:
- (void)updateConstraints
{
[super updateConstraints];
[self bringSubviewToFront:self.containerView];
}
Tenga en cuenta que si usa UINavigationController con una barra de herramientas personalizada, debe obligarlo a actualizar su diseño antes de agregar sus subvistas personalizadas.
Hay una manera extraña de hacerlo.
[self.textInputbar sendSubviewToBack:[self.textInputbar.subviews lastObject]];
He resuelto este problema en mi caso. Reescribo el método layoutSubviews en la subclase de UIToobar y cambio el userInteractionEnable de _UIToolbarContentView en 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;
}
}
}
Para resolver el problema para iOS11 (compatible con versiones inferiores), solo necesita hacer una layoutSubview justo después de que se agregó UIToolBar como subvista a la jerarquía de UI.
En este caso _UIToolbarContentView desciende a la primera subvista de UIToolBar, y puede agregar todas sus subvistas más arriba como antes.
Por ejemplo en ObjC ,
UIToolbar *toolbar = [UIToolbar new];
[self addSubview: toolbar];
[toolbar layoutIfNeeded];
<here one can add all subviews needed>
El mismo problema ocurre con slacktextviewcontroller
Puedes usar el hitTest(_:with:) .
Primero, crea una propiedad
contentViewenUIToolbar:open private(set) var contentView: UIView = UIView()Luego, haga que el marco de
contentViewel mismo que el deUIToolbar. Por ejemplo:contentView.frame = bounds contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight] addSubview(contentView)Finalmente, anule el
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 } }
En esta situación, si desea personalizar una barra de herramientas simplemente agregando vistas adicionales, debe agregarlas a contentView para que se posicionen adecuadamente.