• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018 The Flutter 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 "NativeViewController.h"
6
7@interface NativeViewController ()
8
9@end
10
11@implementation NativeViewController {
12  int _counter;
13  UILabel* _incrementLabel;
14}
15
16- (instancetype)initWithDelegate:(id<NativeViewControllerDelegate>)delegate {
17  self = [super initWithNibName:nil bundle:nil];
18  if (self) {
19    self.delegate = delegate;
20  }
21  return self;
22}
23
24- (instancetype)initWithCoder:(NSCoder *)aDecoder {
25  return [self initWithDelegate:nil];
26}
27
28-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
29   return [self initWithDelegate:nil];
30}
31
32- (void)viewDidLoad {
33    [super viewDidLoad];
34
35    self.title = @"Native iOS View";
36    self.view.backgroundColor = UIColor.lightGrayColor;
37    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc]
38                                                initWithTitle:@"Back"
39                                                        style:UIBarButtonItemStylePlain
40                                                       target:nil
41                                                       action:nil];
42
43    _incrementLabel = [self addIncrementLabel];
44    UIStackView* footer = [self addFooter];
45
46    _incrementLabel.translatesAutoresizingMaskIntoConstraints = false;
47    footer.translatesAutoresizingMaskIntoConstraints = false;
48    UILayoutGuide* marginsGuide = self.view.layoutMarginsGuide;
49    NSMutableArray* array = [[NSMutableArray alloc] init];
50    [array addObject:[_incrementLabel.centerXAnchor
51                         constraintEqualToAnchor:self.view.centerXAnchor]];
52    [array addObject:[_incrementLabel.centerYAnchor
53                         constraintEqualToAnchor:self.view.centerYAnchor]];
54    [array addObject:[footer.centerXAnchor
55                         constraintEqualToAnchor:self.view.centerXAnchor]];
56    [array addObject:[footer.widthAnchor
57                         constraintEqualToAnchor:marginsGuide.widthAnchor]];
58    [array addObject:[footer.bottomAnchor
59                         constraintEqualToAnchor:marginsGuide.bottomAnchor]];
60
61    [NSLayoutConstraint activateConstraints:array];
62    [self updateIncrementLabel];
63}
64
65/// Adds a label to the view that will contain the counter text.
66///
67/// - Returns: The new label.
68-(UILabel*) addIncrementLabel {
69  UILabel* incrementLabel = [[UILabel alloc] init];
70  incrementLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody];
71  incrementLabel.textColor = UIColor.blackColor;
72  incrementLabel.accessibilityIdentifier = @"counter_on_iOS";
73  [self.view addSubview:incrementLabel];
74  return incrementLabel;
75}
76
77/// Adds a horizontal stack to the view, anchored to the bottom.
78///
79/// - Returns: The new stack.
80-(UIStackView*) addFooter {
81  UILabel* mainLabel = [self createMainLabel];
82  UIButton* incrementButton = [self createIncrementButton];
83  UIStackView* stackView = [[UIStackView alloc] initWithFrame:self.view.frame];
84  [stackView addArrangedSubview:mainLabel];
85  [stackView addArrangedSubview:incrementButton];
86  stackView.axis = UILayoutConstraintAxisHorizontal;
87  stackView.alignment = UIStackViewAlignmentBottom;
88  [self.view addSubview:stackView];
89  return stackView;
90}
91
92/// Creates a label identifying this view.  Does not add it to the view.
93///
94/// - Returns: The new label.
95-(UILabel*) createMainLabel {
96  UILabel* mainLabel = [[UILabel alloc] init];
97  mainLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleTitle1];
98  mainLabel.textColor = UIColor.blackColor;
99  mainLabel.text = @"Native";
100  return mainLabel;
101}
102
103/// Creates a button that will increment a counter.  Does not add it to the view.
104///
105/// - Returns: The new button.
106-(UIButton*) createIncrementButton {
107  UIButton *incrementButton = [UIButton buttonWithType:UIButtonTypeSystem];
108  incrementButton.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleTitle2];
109  [incrementButton setTitle:@"Add" forState:UIControlStateNormal];
110  incrementButton.accessibilityLabel = @"Increment via iOS";
111  incrementButton.layer.cornerRadius = 15.0;
112  [incrementButton addTarget:self
113                      action:@selector(handleIncrement:)
114            forControlEvents:UIControlEventTouchUpInside];
115  return incrementButton;
116}
117
118// MARK: - Actions
119
120/// Action triggered from tapping on the increment button.  Triggers a corresponding event in the
121/// delegate if one is available, otherwise increments our internal counter.
122-(void) handleIncrement:(UIButton*)sender {
123  if (self.delegate) {
124    [self.delegate didTapIncrementButton];
125  } else {
126    [self didReceiveIncrement];
127  }
128}
129
130/// Updates the increment label text to match the increment counter.
131-(void) updateIncrementLabel {
132  _incrementLabel.text = [NSString
133      stringWithFormat:@"%@ tapped %d %@.",
134                       self.delegate == nil ? @"Button" : @"Flutter button",
135                       _counter, _counter == 1 ? @"time" : @"times"];
136}
137
138/// Increments our internal counter and updates the view.
139-(void) didReceiveIncrement {
140  _counter += 1;
141  [self updateIncrementLabel];
142}
143
144@end
145