blob: 583673a37422557b465e18813f18af679b370040 [file] [log] [blame]
// Copyright 2013 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/autofill/form_suggestion_view.h"
#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "components/autofill/core/browser/popup_item_ids.h"
#import "components/autofill/ios/browser/form_suggestion.h"
#import "ios/chrome/browser/autofill/form_suggestion_label.h"
#import "ios/chrome/browser/autofill/form_suggestion_view_client.h"
#include "ios/chrome/common/ui_util/constraints_ui_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// Vertical margin between suggestions and the edge of the suggestion content
// frame.
const CGFloat kSuggestionVerticalMargin = 6;
// Horizontal margin around suggestions (i.e. between suggestions, and between
// the end suggestions and the suggestion content frame).
const CGFloat kSuggestionHorizontalMargin = 6;
} // namespace
@interface FormSuggestionView ()
// Creates and adds subviews.
- (void)setupSubviews;
@end
@implementation FormSuggestionView {
// The FormSuggestions that are displayed by this view.
NSArray* _suggestions;
// The stack view with the suggestions.
UIStackView* _stackView;
// Handles user interactions.
id<FormSuggestionViewClient> _client;
}
@synthesize trailingView = _trailingView;
- (instancetype)initWithFrame:(CGRect)frame
client:(id<FormSuggestionViewClient>)client
suggestions:(NSArray<FormSuggestion*>*)suggestions {
self = [super initWithFrame:frame];
if (self) {
_client = client;
_suggestions = [suggestions copy];
}
return self;
}
#pragma mark - UIView
- (void)willMoveToSuperview:(UIView*)newSuperview {
// Create and add subviews the first time this moves to a superview.
if (newSuperview && self.subviews.count == 0) {
[self setupSubviews];
}
[super willMoveToSuperview:newSuperview];
}
#pragma mark - Helper methods
- (void)setupSubviews {
self.showsVerticalScrollIndicator = NO;
self.showsHorizontalScrollIndicator = NO;
self.canCancelContentTouches = YES;
UIStackView* stackView = [[UIStackView alloc] initWithArrangedSubviews:@[]];
stackView.axis = UILayoutConstraintAxisHorizontal;
stackView.layoutMarginsRelativeArrangement = YES;
stackView.layoutMargins =
UIEdgeInsetsMake(kSuggestionVerticalMargin, kSuggestionHorizontalMargin,
kSuggestionVerticalMargin, kSuggestionHorizontalMargin);
stackView.spacing = kSuggestionHorizontalMargin;
stackView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:stackView];
AddSameConstraints(stackView, self);
[stackView.heightAnchor constraintEqualToAnchor:self.heightAnchor].active =
true;
// Rotate the UIScrollView and its UIStackView subview 180 degrees so that the
// first suggestion actually shows up first.
if (base::i18n::IsRTL()) {
self.transform = CGAffineTransformMakeRotation(M_PI);
stackView.transform = CGAffineTransformMakeRotation(M_PI);
}
auto setupBlock = ^(FormSuggestion* suggestion, NSUInteger idx, BOOL* stop) {
// Disable user interaction with suggestion if it is Google Pay logo.
BOOL userInteractionEnabled =
suggestion.identifier != autofill::POPUP_ITEM_ID_GOOGLE_PAY_BRANDING;
UIView* label =
[[FormSuggestionLabel alloc] initWithSuggestion:suggestion
index:idx
userInteractionEnabled:userInteractionEnabled
numSuggestions:[_suggestions count]
client:_client];
[stackView addArrangedSubview:label];
// If first suggestion is Google Pay logo animate it below the fold.
if (idx == 0U &&
suggestion.identifier == autofill::POPUP_ITEM_ID_GOOGLE_PAY_BRANDING) {
const CGFloat firstLabelWidth =
[label systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]
.width +
kSuggestionHorizontalMargin;
dispatch_time_t popTime =
dispatch_time(DISPATCH_TIME_NOW, 0.5 * NSEC_PER_SEC);
__weak FormSuggestionView* weakSelf = self;
dispatch_after(popTime, dispatch_get_main_queue(), ^{
[weakSelf setContentOffset:CGPointMake(firstLabelWidth,
weakSelf.contentOffset.y)
animated:YES];
});
}
};
[_suggestions enumerateObjectsUsingBlock:setupBlock];
if (self.trailingView) {
[stackView addArrangedSubview:self.trailingView];
}
_stackView = stackView;
}
#pragma mark - Getters
- (NSArray*)suggestions {
return _suggestions;
}
#pragma mark - Setters
- (void)setTrailingView:(UIView*)subview {
if (_trailingView.superview) {
[_stackView removeArrangedSubview:_trailingView];
}
_trailingView = subview;
if (_stackView) {
[_stackView addArrangedSubview:_trailingView];
}
}
@end