我知道有很多关于这个主题的文档,而且我从阅读的内容中学到了很多东西。我的问题是我开始在 viewcontroller 中创建自定义 UIView & 现在当我试图让它成为 UIView 自己的类,以便在工作应用程序中调用和使用时,我很困惑什么我需要做些什么来实现它。
该类的总体目标是能够选择一个按钮或一个 View Controller ,它将实例化自定义 View ,然后显示。用户的视觉效果是他们单击按钮,然后一个窗口将从按钮的边界动画出现(尽管下面的代码当前使用左上角的定位),然后显示开关和标签的组合,以及带有后退和保存按钮。
您可以从我的代码中看到实现此过程所需的内容,我已设法将其实现为单个函数(同样,这是在 View Controller 中创建的)。我现在所追求的是要导入自定义 View ,然后在主视图 Controller 按钮的操作上,将 View 添加到 self.view。
- (void)makeBox{
//view bounds
CGFloat viewWidth = CGRectGetWidth(self.view.frame);
CGFloat viewHeight = CGRectGetHeight(self.view.frame);
//red box x, y & size
CGFloat startx = (viewWidth / 100) * 10;
CGFloat starty = (viewHeight /100) * 20;
CGFloat width = (viewWidth / 100) * 80;
CGFloat height = (viewHeight /100) * 70;
CGRect view1Frame = CGRectMake(startx, starty, width, height);
//label & switch frame
CGRect labelMR = CGRectMake(10, ((height / 100) * 12), ((width / 100) * 80) - 7.5, 25);
CGRect switchMR = CGRectMake(((width / 100) * 80) + 7.5, ((height / 100) * 11), ((width / 100) * 10), 15);
//this is repeated for 6 other labels & switches
CGRect backButtonR = CGRectMake(5, 5, 50, 35);
CGRect saveButtonR = CGRectMake((width - 50), 5, 50, 35);
if (!self.view1) {
self.switchM = [[UISwitch alloc] initWithFrame:switchMR];
self.switchM.tag = 10;
if(self.monday){ //self.monday refers to a BOOL property of the viewcontroller that this was originally made in
self.switchM.on = true;
} else{
self.switchM.on = false;
}
[self.switchM addTarget:self action:@selector(switched:) forControlEvents:UIControlEventTouchUpInside];
// this switch instantiation process is repeated 6 other times
self.backButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[self.backButton addTarget:self
action:@selector(hideBox)
forControlEvents:UIControlEventTouchUpInside];
[self.backButton setTitle:@"Back" forState:UIControlStateNormal];
self.backButton.frame = backButtonR;
self.saveButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[self.saveButton addTarget:self
action:@selector(daysChanged)
forControlEvents:UIControlEventTouchUpInside];
[self.saveButton setTitle:@"Save" forState:UIControlStateNormal];
self.saveButton.frame = saveButtonR;
self.labelM = [[UILabel alloc] initWithFrame:labelMR];
self.labelM.layer.masksToBounds = YES;
self.labelM.layer.cornerRadius = 5;
self.labelM.layer.borderColor = [UIColor blackColor].CGColor;
self.labelM.layer.borderWidth = .5;
self.labelM.text = @" Monday";
self.labelM.backgroundColor = [UIColor whiteColor];
//again - repeated 6 times
//use this starting frame to make the 'popover' appear small at first
CGRect startFrame = CGRectMake(10, 10, 10, 10);
self.view1 = [[UIView alloc] initWithFrame:startFrame];
[self.view addSubview:self.view1];
[UIView animateWithDuration:0.5 animations:^(void){
self.view1.layer.cornerRadius = 10;
self.view1.layer.borderColor = [UIColor blackColor].CGColor;
self.view1.layer.borderWidth = .5;
[self.view1 setBackgroundColor:[UIColor lightGrayColor]];
self.view1.frame = view1Frame;
} completion:^(BOOL finished){
[self.view1 addSubview:self.labelM];
[self.view1 addSubview:self.switchM];
//repeat 6 times for other labels & switches
}];
}
else {
[UIView animateWithDuration:0.3 animations:^() {
self.view1.frame = view1Frame;
} completion:^(BOOL finished) {
self.labelM.frame = labelMR;
self.switchM.frame = switchMR;
//repeated for the other 6
self.backButton.frame = backButtonR;
self.saveButton.frame = saveButtonR;
}];
}
}
-(void) hideBox{
//back button was selected
[UIView animateWithDuration:0.5 animations:^(void){
[self.view1 removeFromSuperview];
self.view1 = nil;
}];
}
我明白,当我通过代码执行/调用它时,我需要覆盖 init
或 initWithFrame:
。我是否传递 initWithFrame:
包含的 View Controller 边界,可以在其中计算自定义 View ,我如何处理动画?
我已经成功地设置了委托(delegate)协议(protocol),它会在按下保存按钮时发出通知。那部分我明白了,只是其余部分我不清楚。
最佳答案
首先是一些背景。
通常对于弹出框 Controller ,您有一个透明的 Root View ,其中包含弹出框 View 本身。此 Root View 是包含窗口的大小,通常在 z 顺序上高于所有其他 View 。这有两个原因:
1) 弹出窗口需要绘制在所有其他 View 之上。如果 Root View 不在所有其他 View 之上,则弹出窗口可能会被裁剪,并且不会绘制其所有内容。
2) 用户通常需要一些地方来点击和关闭弹出窗口(实际上是取消操作)。
UIPopoverController 与某些第 3 方弹出窗口一样执行此操作。有些甚至使用他们自己的 UIWindows。
回答您的具体问题:
1) initWithFrame:/setFrame: 应该传递一个 CGRect,它位于将包含该 View 的 View 的坐标空间中。换句话说, super View 。如果您决定使用透明 Root View ,弹出窗口(在屏幕上绘制的部分)将在透明 Root View 的坐标空间中传递一个 CGRect。
2) 通常弹出框的动画如下:
// set initial frame
popover.frame = CGRectMake(x, y, width, 0);
popover.alpha = 0.0;
[rootView addSubview:popover];
[UIView animateWithDuration:0.5
animations:^{
CGRect frame = popover.frame;
frame.size.height = some-height;
popover.frame = frame;
popover.alpha = 1;
}
];
关于iOS,创建自定义弹出窗口样式 UIView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28108403/