blob: 0fc4d6118e17dc19ed719e6c35efc3af145d44db [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/toolbar/legacy_toolbar_view.h"
#import "ios/chrome/browser/ui/toolbar/toolbar_view_delegate.h"
#include "ios/chrome/browser/ui/ui_util.h"
@implementation LegacyToolbarView
@synthesize delegate = delegate_;
@synthesize animatingTransition = animatingTransition_;
@synthesize hitTestBoundsContraintRelaxed = hitTestBoundsContraintRelaxed_;
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
if (IsSafeAreaCompatibleToolbarEnabled()) {
// The minimal width of the toolbar.
// Must be less than or equal to the smallest UIWindow size Chrome can
// be in, which as of M64 is 320.
// Must be greater or equal than the sum of the minimal width (and
// padding) of all of its subviews.
const CGFloat kMinToolbarWidth = 200;
// When the toolbar is not in the view hierarchy, UIKit sets the bounds to
// CGRectZero. This results in the subviews of the toolbars which are
// positioned with autoresizing masks to be moved.
// This constraint enforces a minimum width.
[self.widthAnchor constraintGreaterThanOrEqualToConstant:kMinToolbarWidth]
.active = YES;
}
}
return self;
}
// Some views added to the toolbar have bounds larger than the toolbar bounds
// and still needs to receive touches. The overscroll actions view is one of
// those. That method is overridden in order to still perform hit testing on
// subviews that resides outside the toolbar bounds.
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event {
UIView* hitView = [super hitTest:point withEvent:event];
if (hitView || !self.hitTestBoundsContraintRelaxed)
return hitView;
for (UIView* view in [[self subviews] reverseObjectEnumerator]) {
if (!view.userInteractionEnabled || [view isHidden] || [view alpha] < 0.01)
continue;
const CGPoint convertedPoint = [view convertPoint:point fromView:self];
if ([view pointInside:convertedPoint withEvent:event]) {
hitView = [view hitTest:convertedPoint withEvent:event];
if (hitView)
break;
}
}
return hitView;
}
- (void)setFrame:(CGRect)frame {
[super setFrame:frame];
[delegate_ toolbarDidLayout];
}
- (void)layoutSubviews {
[super layoutSubviews];
[delegate_ toolbarDidLayout];
}
- (void)didMoveToWindow {
[super didMoveToWindow];
[delegate_ windowDidChange];
}
- (id<CAAction>)actionForLayer:(CALayer*)layer forKey:(NSString*)event {
// Don't allow UIView block-based animations if we're already performing
// explicit transition animations.
if (self.animatingTransition)
return (id<CAAction>)[NSNull null];
return [super actionForLayer:layer forKey:event];
}
- (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
[super traitCollectionDidChange:previousTraitCollection];
[delegate_ traitCollectionDidChange];
}
@end