在 UIScrollView 中单击按钮时在另一个下方添加 UITextFields
Adding UITextFields one below another on button click in a UIScrollView
我有一个带有多个 components.I 的 UIScrollView,需要以这样一种方式添加 UITextfields,即在点击一个按钮时,文本字段将在另一个下方添加一个 vertically.for 例如,如果按钮被点击 100 次。应该添加 100 个 uitextfields,这个 uitextfield 下面还有组件,所以 uiscrollview 应该相应地调整它的高度。
注意: 原始答案已用填充/获取示例代码编辑。
这是一个简单的例子。
向滚动视图添加一个UIStackView
(垂直轴)。每次点击按钮,创建一个新的 UITextField
并将其添加为堆栈视图的 arrangedSubview
。
堆栈视图将自动垂直扩展,其约束将自动处理滚动视图的内容大小。
- 新字段将使用占位符字符串进行初始化。
- 然后点击 "Fill Fields" 按钮会将每个字段的文本设置为示例数据数组中的值。
- 点击 "Get Text" 按钮会将每个字段的文本记录到调试控制台。
ViewController.h
//
// ViewController.h
//
// Created by Don Mag on 12/3/19.
//
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
ViewController.m
//
// ViewController.m
//
// Created by Don Mag on 12/3/19.
//
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) UIButton *theButton;
@property (strong, nonatomic) UIButton *fillButton;
@property (strong, nonatomic) UIButton *getButton;
@property (strong, nonatomic) UIScrollView *theScrollView;
@property (strong, nonatomic) UIStackView *theStackView;
@property (strong, nonatomic) NSMutableArray *theData;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor whiteColor]];
// instantiate buttons, scrollView and stackViews
// adds a new text field
_theButton = [UIButton new];
[_theButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[_theButton setTitle:@"Add Field" forState:UIControlStateNormal];
[_theButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
[_theButton setBackgroundColor:[UIColor redColor]];
// fills the fields with sample data
_fillButton = [UIButton new];
[_fillButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[_fillButton setTitle:@"Fill Fields" forState:UIControlStateNormal];
[_fillButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
[_fillButton setBackgroundColor:[UIColor redColor]];
// logs the text of each field to debug console
_getButton = [UIButton new];
[_getButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[_getButton setTitle:@"Get Text" forState:UIControlStateNormal];
[_getButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
[_getButton setBackgroundColor:[UIColor redColor]];
// scroll view will hold the stack view filled with fields
_theScrollView = [UIScrollView new];
[_theScrollView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_theScrollView setBackgroundColor:[UIColor cyanColor]];
// stack view to hold the new fields
_theStackView = [UIStackView new];
[_theStackView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_theStackView setAxis:UILayoutConstraintAxisVertical];
[_theStackView setSpacing:8.0];
// stack view for buttons
UIStackView *buttonsStackView = [UIStackView new];
[buttonsStackView setTranslatesAutoresizingMaskIntoConstraints:NO];
[buttonsStackView setAxis:UILayoutConstraintAxisHorizontal];
[buttonsStackView setSpacing:8.0];
// add buttons to the buttons stack view
[buttonsStackView addArrangedSubview:_theButton];
[buttonsStackView addArrangedSubview:_fillButton];
[buttonsStackView addArrangedSubview:_getButton];
// add button stack view and scrollView to view
[self.view addSubview:buttonsStackView];
[self.view addSubview:_theScrollView];
// add stackView to scrollView
[_theScrollView addSubview:_theStackView];
UILayoutGuide *g = self.view.safeAreaLayoutGuide;
UILayoutGuide *sg = _theScrollView.contentLayoutGuide;
[NSLayoutConstraint activateConstraints:@[
// constrain buttons 20-pts from top, centered horizontally
[buttonsStackView.topAnchor constraintEqualToAnchor:g.topAnchor constant:20.0],
[buttonsStackView.centerXAnchor constraintEqualToAnchor:g.centerXAnchor constant:0.0],
// constrai scrollView 20-pts below button, 20-pts on each side and bottom
[_theScrollView.topAnchor constraintEqualToAnchor:_theButton.bottomAnchor constant:20.0],
[_theScrollView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:-20.0],
[_theScrollView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:20.0],
[_theScrollView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:-20.0],
// constrain stackView 8-pts on each side
[_theStackView.topAnchor constraintEqualToAnchor:sg.topAnchor constant:8.0],
[_theStackView.bottomAnchor constraintEqualToAnchor:sg.bottomAnchor constant:-8.0],
[_theStackView.leadingAnchor constraintEqualToAnchor:sg.leadingAnchor constant:8.0],
[_theStackView.trailingAnchor constraintEqualToAnchor:sg.trailingAnchor constant:-8.0],
// constrain stackView width to scrollView frame width minus 16-pts (for 8-pts on each side)
[_theStackView.widthAnchor constraintEqualToAnchor:_theScrollView.frameLayoutGuide.widthAnchor constant:-16.0],
]
];
[_theButton addTarget:self action:@selector(addTextField:) forControlEvents:UIControlEventTouchUpInside];
[_fillButton addTarget:self action:@selector(fillFields:) forControlEvents:UIControlEventTouchUpInside];
[_getButton addTarget:self action:@selector(getFields:) forControlEvents:UIControlEventTouchUpInside];
// sample data to fill the fields with
NSString *s = @"This is just random text that will be used to fill the text fields when the fill button is tapped";
_theData = [s componentsSeparatedByString:@" "].mutableCopy;
}
- (void)fillFields:(id)sender {
// set the text of each field based on the data array
NSInteger idx = 0;
for (UITextField *f in _theStackView.arrangedSubviews) {
// make sure we don't have more fields than our data array
if (idx < _theData.count) {
f.text = _theData[idx++];
}
}
}
- (void)getFields:(id)sender {
// log the text of each field to debug cosole
for (UITextField *f in _theStackView.arrangedSubviews) {
NSLog(@"%@", f.text);
}
}
- (void)addTextField:(id)sender {
// instantiate a new text field
UITextField *f = [UITextField new];
[f setBorderStyle:UITextBorderStyleRoundedRect];
[f setBackgroundColor:[UIColor whiteColor]];
// add it to the stack view
[_theStackView addArrangedSubview:f];
// set its placeholder text (just to make it easy to see what we're doing)
[f setPlaceholder:[NSString stringWithFormat:@"Text Field %ld", _theStackView.arrangedSubviews.count]];
dispatch_async(dispatch_get_main_queue(), ^{
// auto-scroll to bottom so newly added text field is visible
CGRect r = CGRectMake(0.0, self.theScrollView.contentSize.height - 1.0, 1.0, 1.0);
[self.theScrollView scrollRectToVisible:r animated:YES];
});
}
@end
点击 3 次后的结果:
点击足够多后需要滚动:
点击 "Fill Fields" 按钮后:
我有一个带有多个 components.I 的 UIScrollView,需要以这样一种方式添加 UITextfields,即在点击一个按钮时,文本字段将在另一个下方添加一个 vertically.for 例如,如果按钮被点击 100 次。应该添加 100 个 uitextfields,这个 uitextfield 下面还有组件,所以 uiscrollview 应该相应地调整它的高度。
注意: 原始答案已用填充/获取示例代码编辑。
这是一个简单的例子。
向滚动视图添加一个UIStackView
(垂直轴)。每次点击按钮,创建一个新的 UITextField
并将其添加为堆栈视图的 arrangedSubview
。
堆栈视图将自动垂直扩展,其约束将自动处理滚动视图的内容大小。
- 新字段将使用占位符字符串进行初始化。
- 然后点击 "Fill Fields" 按钮会将每个字段的文本设置为示例数据数组中的值。
- 点击 "Get Text" 按钮会将每个字段的文本记录到调试控制台。
ViewController.h
//
// ViewController.h
//
// Created by Don Mag on 12/3/19.
//
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
ViewController.m
//
// ViewController.m
//
// Created by Don Mag on 12/3/19.
//
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) UIButton *theButton;
@property (strong, nonatomic) UIButton *fillButton;
@property (strong, nonatomic) UIButton *getButton;
@property (strong, nonatomic) UIScrollView *theScrollView;
@property (strong, nonatomic) UIStackView *theStackView;
@property (strong, nonatomic) NSMutableArray *theData;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view setBackgroundColor:[UIColor whiteColor]];
// instantiate buttons, scrollView and stackViews
// adds a new text field
_theButton = [UIButton new];
[_theButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[_theButton setTitle:@"Add Field" forState:UIControlStateNormal];
[_theButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
[_theButton setBackgroundColor:[UIColor redColor]];
// fills the fields with sample data
_fillButton = [UIButton new];
[_fillButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[_fillButton setTitle:@"Fill Fields" forState:UIControlStateNormal];
[_fillButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
[_fillButton setBackgroundColor:[UIColor redColor]];
// logs the text of each field to debug console
_getButton = [UIButton new];
[_getButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[_getButton setTitle:@"Get Text" forState:UIControlStateNormal];
[_getButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateHighlighted];
[_getButton setBackgroundColor:[UIColor redColor]];
// scroll view will hold the stack view filled with fields
_theScrollView = [UIScrollView new];
[_theScrollView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_theScrollView setBackgroundColor:[UIColor cyanColor]];
// stack view to hold the new fields
_theStackView = [UIStackView new];
[_theStackView setTranslatesAutoresizingMaskIntoConstraints:NO];
[_theStackView setAxis:UILayoutConstraintAxisVertical];
[_theStackView setSpacing:8.0];
// stack view for buttons
UIStackView *buttonsStackView = [UIStackView new];
[buttonsStackView setTranslatesAutoresizingMaskIntoConstraints:NO];
[buttonsStackView setAxis:UILayoutConstraintAxisHorizontal];
[buttonsStackView setSpacing:8.0];
// add buttons to the buttons stack view
[buttonsStackView addArrangedSubview:_theButton];
[buttonsStackView addArrangedSubview:_fillButton];
[buttonsStackView addArrangedSubview:_getButton];
// add button stack view and scrollView to view
[self.view addSubview:buttonsStackView];
[self.view addSubview:_theScrollView];
// add stackView to scrollView
[_theScrollView addSubview:_theStackView];
UILayoutGuide *g = self.view.safeAreaLayoutGuide;
UILayoutGuide *sg = _theScrollView.contentLayoutGuide;
[NSLayoutConstraint activateConstraints:@[
// constrain buttons 20-pts from top, centered horizontally
[buttonsStackView.topAnchor constraintEqualToAnchor:g.topAnchor constant:20.0],
[buttonsStackView.centerXAnchor constraintEqualToAnchor:g.centerXAnchor constant:0.0],
// constrai scrollView 20-pts below button, 20-pts on each side and bottom
[_theScrollView.topAnchor constraintEqualToAnchor:_theButton.bottomAnchor constant:20.0],
[_theScrollView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:-20.0],
[_theScrollView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:20.0],
[_theScrollView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:-20.0],
// constrain stackView 8-pts on each side
[_theStackView.topAnchor constraintEqualToAnchor:sg.topAnchor constant:8.0],
[_theStackView.bottomAnchor constraintEqualToAnchor:sg.bottomAnchor constant:-8.0],
[_theStackView.leadingAnchor constraintEqualToAnchor:sg.leadingAnchor constant:8.0],
[_theStackView.trailingAnchor constraintEqualToAnchor:sg.trailingAnchor constant:-8.0],
// constrain stackView width to scrollView frame width minus 16-pts (for 8-pts on each side)
[_theStackView.widthAnchor constraintEqualToAnchor:_theScrollView.frameLayoutGuide.widthAnchor constant:-16.0],
]
];
[_theButton addTarget:self action:@selector(addTextField:) forControlEvents:UIControlEventTouchUpInside];
[_fillButton addTarget:self action:@selector(fillFields:) forControlEvents:UIControlEventTouchUpInside];
[_getButton addTarget:self action:@selector(getFields:) forControlEvents:UIControlEventTouchUpInside];
// sample data to fill the fields with
NSString *s = @"This is just random text that will be used to fill the text fields when the fill button is tapped";
_theData = [s componentsSeparatedByString:@" "].mutableCopy;
}
- (void)fillFields:(id)sender {
// set the text of each field based on the data array
NSInteger idx = 0;
for (UITextField *f in _theStackView.arrangedSubviews) {
// make sure we don't have more fields than our data array
if (idx < _theData.count) {
f.text = _theData[idx++];
}
}
}
- (void)getFields:(id)sender {
// log the text of each field to debug cosole
for (UITextField *f in _theStackView.arrangedSubviews) {
NSLog(@"%@", f.text);
}
}
- (void)addTextField:(id)sender {
// instantiate a new text field
UITextField *f = [UITextField new];
[f setBorderStyle:UITextBorderStyleRoundedRect];
[f setBackgroundColor:[UIColor whiteColor]];
// add it to the stack view
[_theStackView addArrangedSubview:f];
// set its placeholder text (just to make it easy to see what we're doing)
[f setPlaceholder:[NSString stringWithFormat:@"Text Field %ld", _theStackView.arrangedSubviews.count]];
dispatch_async(dispatch_get_main_queue(), ^{
// auto-scroll to bottom so newly added text field is visible
CGRect r = CGRectMake(0.0, self.theScrollView.contentSize.height - 1.0, 1.0, 1.0);
[self.theScrollView scrollRectToVisible:r animated:YES];
});
}
@end
点击 3 次后的结果:
点击足够多后需要滚动:
点击 "Fill Fields" 按钮后: