1// Copyright 2017 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#import "ios/chrome/search_widget_extension/search_action_view.h" 6 7#import <NotificationCenter/NotificationCenter.h> 8 9#include "base/check.h" 10#import "ios/chrome/common/ui/util/constraints_ui_util.h" 11#import "ios/chrome/search_widget_extension/search_widget_constants.h" 12 13#if !defined(__has_feature) || !__has_feature(objc_arc) 14#error "This file requires ARC support." 15#endif 16 17namespace { 18 19const CGFloat kActionButtonSize = 55; 20const CGFloat kIconSize = 35; 21 22} // namespace 23 24@implementation SearchActionView 25 26- (instancetype)initWithActionTarget:(id)target 27 actionSelector:(SEL)actionSelector 28 title:(NSString*)title 29 imageName:(NSString*)imageName { 30 DCHECK(target); 31 self = [super initWithFrame:CGRectZero]; 32 if (self) { 33 self.translatesAutoresizingMaskIntoConstraints = NO; 34 35 UIVibrancyEffect* primaryEffect = nil; 36 UIVibrancyEffect* secondaryEffect = nil; 37 UIVibrancyEffect* iconBackgroundEffect = nil; 38 if (@available(iOS 13, *)) { 39 primaryEffect = [UIVibrancyEffect 40 widgetEffectForVibrancyStyle:UIVibrancyEffectStyleLabel]; 41 secondaryEffect = [UIVibrancyEffect 42 widgetEffectForVibrancyStyle:UIVibrancyEffectStyleSecondaryLabel]; 43 iconBackgroundEffect = [UIVibrancyEffect 44 widgetEffectForVibrancyStyle:UIVibrancyEffectStyleTertiaryFill]; 45 } 46#if !defined(__IPHONE_13_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_13_0 47 else { 48 primaryEffect = [UIVibrancyEffect widgetPrimaryVibrancyEffect]; 49 secondaryEffect = [UIVibrancyEffect widgetSecondaryVibrancyEffect]; 50 iconBackgroundEffect = [UIVibrancyEffect widgetSecondaryVibrancyEffect]; 51 } 52#endif 53 DCHECK(primaryEffect); 54 DCHECK(secondaryEffect); 55 DCHECK(iconBackgroundEffect); 56 57 UIVisualEffectView* primaryEffectView = 58 [[UIVisualEffectView alloc] initWithEffect:primaryEffect]; 59 UIVisualEffectView* secondaryEffectView = 60 [[UIVisualEffectView alloc] initWithEffect:secondaryEffect]; 61 UIVisualEffectView* iconBackgroundEffectView = 62 [[UIVisualEffectView alloc] initWithEffect:iconBackgroundEffect]; 63 for (UIVisualEffectView* effectView in @[ 64 primaryEffectView, secondaryEffectView, iconBackgroundEffectView 65 ]) { 66 effectView.translatesAutoresizingMaskIntoConstraints = NO; 67 effectView.userInteractionEnabled = NO; 68 } 69 70 UIView* circleView = [[UIView alloc] initWithFrame:CGRectZero]; 71 circleView.translatesAutoresizingMaskIntoConstraints = NO; 72 if (@available(iOS 13, *)) { 73 circleView.backgroundColor = UIColor.whiteColor; 74 } else { 75 circleView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.05]; 76 } 77 circleView.layer.cornerRadius = kActionButtonSize / 2; 78 [iconBackgroundEffectView.contentView addSubview:circleView]; 79 AddSameConstraints(iconBackgroundEffectView.contentView, circleView); 80 81 UILabel* labelView = [[UILabel alloc] initWithFrame:CGRectZero]; 82 labelView.translatesAutoresizingMaskIntoConstraints = NO; 83 labelView.text = title; 84 labelView.numberOfLines = 0; 85 labelView.textAlignment = NSTextAlignmentCenter; 86 labelView.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption2]; 87 labelView.isAccessibilityElement = NO; 88 [labelView 89 setContentCompressionResistancePriority:UILayoutPriorityRequired 90 forAxis:UILayoutConstraintAxisVertical]; 91 [secondaryEffectView.contentView addSubview:labelView]; 92 AddSameConstraints(secondaryEffectView.contentView, labelView); 93 94 UIStackView* stack = [[UIStackView alloc] initWithArrangedSubviews:@[ 95 iconBackgroundEffectView, secondaryEffectView 96 ]]; 97 stack.axis = UILayoutConstraintAxisVertical; 98 stack.spacing = kIconSpacing; 99 stack.alignment = UIStackViewAlignmentCenter; 100 stack.translatesAutoresizingMaskIntoConstraints = NO; 101 stack.userInteractionEnabled = NO; 102 [self addSubview:stack]; 103 AddSameConstraints(self, stack); 104 105 UIImage* iconImage = [UIImage imageNamed:imageName]; 106 iconImage = 107 [iconImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 108 UIImageView* icon = [[UIImageView alloc] initWithImage:iconImage]; 109 icon.translatesAutoresizingMaskIntoConstraints = NO; 110 [primaryEffectView.contentView addSubview:icon]; 111 AddSameConstraints(primaryEffectView.contentView, icon); 112 [self addSubview:primaryEffectView]; 113 114 [NSLayoutConstraint activateConstraints:@[ 115 [circleView.widthAnchor constraintEqualToConstant:kActionButtonSize], 116 [circleView.heightAnchor constraintEqualToConstant:kActionButtonSize], 117 [icon.widthAnchor constraintEqualToConstant:kIconSize], 118 [icon.heightAnchor constraintEqualToConstant:kIconSize], 119 [icon.centerXAnchor constraintEqualToAnchor:circleView.centerXAnchor], 120 [icon.centerYAnchor constraintEqualToAnchor:circleView.centerYAnchor], 121 ]]; 122 123 self.userInteractionEnabled = YES; 124 [self addTarget:target 125 action:actionSelector 126 forControlEvents:UIControlEventTouchUpInside]; 127 self.accessibilityLabel = title; 128 129 self.highlightableViews = @[ circleView, labelView, icon ]; 130 } 131 return self; 132} 133 134@end 135