material-components_materia.../components/TextControls/examples/MDCTextControlTextFieldTypicalUseExample.m
Andrew Overton 9b9edf9f46
[TextControls] Use system dynamic colors for sensible defaults in iOS 13 (#8818)
MDCFilledTextField and MDCOutlinedTextField are completely unreadable (inaccessible) in iOS 13 dark mode when shown over the system background color. When using `borderStyle`, MDCBaseTextField is completely unreadable in iOS 13 dark mode when shown over _any_ color, because UITextField adds a system background color to the textfield's background. This PR addresses these issues. This PR doesn't affect pre-iOS 13 behavior.

Note that the system placeholder and clear button never pass contrast in dark mode. I know the system clear button doesn't even pass contrast in light mode.

Note that the below gifs are outdated. Here's what it looks like now in dark mode:

<img width="371" alt="Screen Shot 2019-11-14 at 11 40 07 AM" src="https://user-images.githubusercontent.com/8020010/68877158-9a036000-06d3-11ea-8cd2-902a1d2b0eb1.png">

Here's a before gif in iOS 13 dark mode:
![iOS13darkbefore](https://user-images.githubusercontent.com/8020010/68875587-15afdd80-06d1-11ea-8bee-b583a56e4537.gif)

Here's an after gif in iOS 13 light mode:
![iOS13light](https://user-images.githubusercontent.com/8020010/68875641-2c563480-06d1-11ea-8172-5743390bf839.gif)

Here's an after gif in iOS 13 dark mode:

![iOS13Dark](https://user-images.githubusercontent.com/8020010/68875625-282a1700-06d1-11ea-9f3d-2d56d068f3ed.gif)

Closes #8817.
2019-11-14 15:32:45 -05:00

162 lines
6.0 KiB
Objective-C

// Copyright 2019-present the Material Components for iOS authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#import <UIKit/UIKit.h>
#import "MaterialButtons.h"
#import "MaterialContainerScheme.h"
#import "MaterialTextControls.h"
static NSString *const kExampleTitle = @"MDCTextControl TextFields";
static CGFloat const kDefaultPadding = 15.0;
/**
Typical use example showing how to place an @c MDCBaseTextField in a UIViewController.
*/
@interface MDCTextControlTextFieldTypicalUseExample : UIViewController
/** The MDCBaseTextField for this example. */
@property(nonatomic, strong) MDCBaseTextField *baseTextField;
/** The MDCFilledTextField for this example. */
@property(nonatomic, strong) MDCFilledTextField *filledTextField;
/** The MDCOutlinedTextField for this example. */
@property(nonatomic, strong) MDCOutlinedTextField *outlinedTextField;
/** The UIButton that makes the textfield stop being the first responder. */
@property(nonatomic, strong) MDCButton *resignFirstResponderButton;
/** The container scheme injected into this example. */
@property(nonatomic, strong) id<MDCContainerScheming> containerScheme;
@end
@implementation MDCTextControlTextFieldTypicalUseExample
- (void)viewDidLoad {
[super viewDidLoad];
self.title = kExampleTitle;
if (!self.containerScheme) {
MDCContainerScheme *containerScheme = [[MDCContainerScheme alloc] init];
containerScheme.colorScheme =
[[MDCSemanticColorScheme alloc] initWithDefaults:MDCColorSchemeDefaultsMaterial201907];
self.containerScheme = containerScheme;
}
self.view.backgroundColor = self.containerScheme.colorScheme.backgroundColor;
self.resignFirstResponderButton = [self createFirstResponderButton];
[self.view addSubview:self.resignFirstResponderButton];
self.baseTextField = [[MDCBaseTextField alloc] initWithFrame:self.placeholderTextFieldFrame];
self.baseTextField.borderStyle = UITextBorderStyleRoundedRect;
self.baseTextField.label.text = @"This is a label";
self.baseTextField.placeholder = @"This is placeholder text";
self.baseTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
self.baseTextField.leadingAssistiveLabel.text = @"This is leading assistive text";
[self.view addSubview:self.baseTextField];
self.filledTextField = [[MDCFilledTextField alloc] initWithFrame:self.placeholderTextFieldFrame];
self.filledTextField.label.text = @"This is a label";
self.filledTextField.placeholder = @"This is placeholder text";
self.filledTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
self.filledTextField.leadingAssistiveLabel.text = @"This is leading assistive text";
[self.view addSubview:self.filledTextField];
self.outlinedTextField =
[[MDCOutlinedTextField alloc] initWithFrame:self.placeholderTextFieldFrame];
self.outlinedTextField.label.text = @"This is a label";
self.outlinedTextField.placeholder = @"This is placeholder text";
self.outlinedTextField.clearButtonMode = UITextFieldViewModeWhileEditing;
self.outlinedTextField.leadingAssistiveLabel.text = @"This is leading assistive text";
[self.view addSubview:self.outlinedTextField];
}
- (MDCButton *)createFirstResponderButton {
MDCButton *button = [[MDCButton alloc] init];
[button setTitle:@"Resign first responder" forState:UIControlStateNormal];
[button addTarget:self
action:@selector(resignFirstResponderButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
[button sizeToFit];
return button;
}
- (void)resignFirstResponderButtonTapped:(UIButton *)button {
[self.baseTextField resignFirstResponder];
[self.filledTextField resignFirstResponder];
[self.outlinedTextField resignFirstResponder];
}
- (CGFloat)preferredResignFirstResponderMinY {
if (@available(iOS 11.0, *)) {
return (CGFloat)(self.view.safeAreaInsets.top + kDefaultPadding);
} else {
return (CGFloat)120;
}
}
- (CGFloat)preferredTextFieldWidth {
return CGRectGetWidth(self.view.frame) - (2 * kDefaultPadding);
}
- (CGRect)placeholderTextFieldFrame {
return CGRectMake(0, 0, self.preferredTextFieldWidth, 0);
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[self.resignFirstResponderButton sizeToFit];
[self.baseTextField sizeToFit];
[self.filledTextField sizeToFit];
[self.outlinedTextField sizeToFit];
self.resignFirstResponderButton.frame =
CGRectMake(kDefaultPadding, self.preferredResignFirstResponderMinY,
CGRectGetWidth(self.resignFirstResponderButton.frame),
CGRectGetHeight(self.resignFirstResponderButton.frame));
self.filledTextField.frame = CGRectMake(
kDefaultPadding, CGRectGetMaxY(self.resignFirstResponderButton.frame) + kDefaultPadding,
CGRectGetWidth(self.filledTextField.frame), CGRectGetHeight(self.filledTextField.frame));
self.outlinedTextField.frame = CGRectMake(
kDefaultPadding, CGRectGetMaxY(self.filledTextField.frame) + kDefaultPadding,
CGRectGetWidth(self.outlinedTextField.frame), CGRectGetHeight(self.outlinedTextField.frame));
self.baseTextField.frame = CGRectMake(
kDefaultPadding, CGRectGetMaxY(self.outlinedTextField.frame) + kDefaultPadding,
CGRectGetWidth(self.baseTextField.frame), CGRectGetHeight(self.baseTextField.frame));
}
@end
#pragma mark - CatalogByConvention
@implementation MDCTextControlTextFieldTypicalUseExample (CatalogByConvention)
+ (NSDictionary *)catalogMetadata {
return @{
@"breadcrumbs" : @[ @"Text Controls", kExampleTitle ],
@"primaryDemo" : @NO,
@"presentable" : @NO,
};
}
@end