iOS,创建自定义弹出窗口样式 UIView

标签 ios objective-c uiview

我知道有很多关于这个主题的文档,而且我从阅读的内容中学到了很多东西。我的问题是我开始在 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;
    }];
}

我明白,当我通过代码执行/调用它时,我需要覆盖 initinitWithFrame:。我是否传递 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/

相关文章:

iphone - 为什么从服务器请求的文件名以 Unicode 字符开头?

objective-c - iOS(重新)使用 NIB 作为模板

iphone - 减少 UIViewController 的背景 "alpha"

security - iPhone应用程序和安全性?

ios - Xcode 7.1 在归档 swift ios 应用程序时挂起

objective-c - iOS 钥匙串(keychain),存储更多 kSecValueData 项

iOS 动画故障,Y 坐标问题

ios - AVPlayerViewController 中的完成按钮单击事件

android - 如何在应用程序下载页面上区分 Android 和 iOS

objective-c - 将不可变数组传递给可变属性