对于 iOS,我可以混合和匹配以编程方式添加视图并同时使用情节提要吗?

Posted

技术标签:

【中文标题】对于 iOS,我可以混合和匹配以编程方式添加视图并同时使用情节提要吗?【英文标题】:Can I mix and match programmatic adding of views and use a storyboard at the same time for iOS? 【发布时间】:2014-11-25 15:56:02 【问题描述】:

我的故事板中有一个特定视图控制器的默认布局。我想以编程方式添加一些东西,但我不确定如何去做,以便它调整我其他视图的布局。

由于我只是将东西拖放到布局中,因此没有像 android 中那样清晰的结构(布局中的布局、相对性等)。

例如,我希望能够单击一个视图,然后在该视图下方展开一个图表,将每个视图向下推到展开的视图下方。

目前,我可以在布局中的特定位置添加一个视图,但它会在其他视图之后,除非它前面没有任何东西可以在后面。

所以我想我是在问我是否可以在情节提要中完成大部分布局,并通过这种方式为它们提供某种结构,然后以编程方式在项目之间添加内容。

我应该以编程方式完成所有事情吗?这需要我进行一些修改,因为在我的视图控制器和东西之间的交互方面,所有内容都已经在我的故事板中了。

谢谢!

【问题讨论】:

【参考方案1】:

您应该在 Interface Builder 中正确构建视图,您可以使用约束来做到这一点。当然,您也可以通过编程方式添加视图。请记住,Interface Builder 除了定义一个文件来存储接口结构以从 nib 加载它之外,什么也不做。 因此,您只需使用addSubview 方法以编程方式添加您的视图,并在代码中以相同的方式添加您的约束。

这些方法可能会派上用场来更新您的视图:

[self.view setNeedsLayout];
[self.view setNeedsUpdateConstraints];
[self.view setNeedsDisplay];

【讨论】:

【参考方案2】:

答案是“当然”。 故事板在这里仅用于放置将始终显示的元素。 之后,如果你想让一些视图出现和消失,你必须以编程方式进行;)而且真的很简单

看看这个,当我点击在故事板中创建的按钮时,记事本方法是一个 IBAction。

- (IBAction)Notepad:(id)sender 
    if(!isAppearing)
        isAppearing = YES;
        if(notepad==nil)
        
            [self Notepad_Show];
        
        else
        
            [self Notepad_Hide];
        
    



-(void)Notepad_Show

    [self Recherche_Hide];

    DB_Plist* plist = [[DB_Plist alloc] initDatabase];
    float notepadWidth = 300;
    float notepadHeight = 500;

    notepad = [[UIView alloc] initWithFrame:CGRectMake(500, 80, notepadWidth, notepadHeight)];

    UIImageView* background = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, notepadWidth, 0)];
    [background setImage:[UIImage imageNamed:@"notepad.png"]];

    UILabel* titre = [[UILabel alloc] initWithFrame:CGRectMake(0, 10, notepadWidth, 30)];
    [titre setText:[language BlocNotes]];
    [titre setTextAlignment:NSTextAlignmentCenter];
    [titre setFont:[UIFont fontWithName:@"Verdana" size:24]];

    UITextView* textView = [[UITextView alloc] initWithFrame:CGRectMake(40, 40, notepadWidth-50, notepadHeight)];
    [textView setFont:[UIFont fontWithName:@"Verdana" size:18]];
    [textView setBackgroundColor:[UIColor clearColor]];
    [textView setText:[plist Get_Notepad]];

    [notepad addSubview:background];

    [UIView animateWithDuration:ANIMDURATION
                          delay:0.0f
                        options: UIViewAnimationOptionTransitionNone
                     animations:^
                         CGRect viewFrame = background.frame;
                         viewFrame.size.height = notepadHeight;
                         [background setFrame:viewFrame];

                     
                     completion:^(BOOL finished)
                         [notepad addSubview:textView];
                         [notepad addSubview:titre];
                         isAppearing = NO;
                     ];


    [self.view addSubview:notepad];


-(void)Notepad_Hide

    if(notepad!=nil)
        DB_Plist* plist = [[DB_Plist alloc] initDatabase];
        UITextView* textView = [notepad.subviews objectAtIndex:1];
        [plist Set_Notepad:textView.text];

        NSArray* SubViews = [notepad subviews];
        for (int i = 0; i < [SubViews count]; i++)
        
            if(i!=0)
            
                UIView* tempView = [SubViews objectAtIndex:i];
                [tempView removeFromSuperview];
            
        

        [UIView animateWithDuration:ANIMDURATION
                              delay:0.0f
                            options: UIViewAnimationOptionTransitionNone
                         animations:^
                             CGRect viewFrame = notepad.frame;
                             viewFrame.size.height = 0;
                             [notepad setFrame:viewFrame];

                             NSArray* SubViews = [notepad subviews];
                             for (int i = 0; i < [SubViews count]; i++)
                             
                                 UIView* tempView = [SubViews objectAtIndex:i];
                                 CGRect viewFrame = tempView.frame;
                                 viewFrame.size.height = 0;
                                 [tempView setFrame:viewFrame];
                             

                         
                         completion:^(BOOL finished)
                             NSArray* SubViews = [notepad subviews];
                             for (int i = 0; i < [SubViews count]; i++)
                             
                                 UIView* tempView = [SubViews objectAtIndex:i];
                                 [tempView removeFromSuperview];
                                 tempView = nil;
                             
                             [notepad removeFromSuperview];
                             notepad = nil;
                             isAppearing = NO;
                         ];
    

编辑:不要评判我^^我在学习Obj-C时写了这个!这只是为了向您展示,当您从 Storyboard 中点击一个项目时,您可以通过编程方式创建字段

【讨论】:

这会改变周围的观点吗?我知道我可以添加/删除它们,但主要是当我以编程方式添加视图时,默认情节提要中的其他视图如何移动。 不是它没有。视图不会移动,否则您必须自己动手。子视图具有层次结构。它们不在同一平面上,那么为什么子视图会移动? ^^ 这基本上就是我想知道的。如果我单击页面中间的某些内容,我希望它从中间展开并在我单击的内容下方显示某些内容,同时将我现在单击的内容下方的所有内容推到展开的项目下方。 然后,您必须自己为所有视图设置动画。不要忘记,你可以轻松做到,但它会给用户带来视觉上的错觉^^ 你想要在 Facebook App 中打开菜单时做同样的效果,但是从屏幕中间? (例如 ofc)。我说的对吗? 大声笑,是的,这就是我的问题所在。如果可以使用混合物来做到这一点。我不这么认为。更重要的是,如果您要单击一个选项,那么下面会出现更多内容。就像您要单击股票价值一样,其下方会显示一个图表,显示趋势。我正在做类似的事情。【参考方案3】:

如果您的视图布局在 xib 文件中,那么您可以通过编程在 xib 文件创建的界面上添加视图。通过使用 addSubview(myCustomView) 和 myCustomView.isHidden = true 创建视图并添加/隐藏它们。请记住在添加子视图后还要添加约束。

【讨论】:

以上是关于对于 iOS,我可以混合和匹配以编程方式添加视图并同时使用情节提要吗?的主要内容,如果未能解决你的问题,请参考以下文章

IOS swift scrollview以编程方式

使用 xamarin.ios c# 以编程方式添加嵌套的堆栈视图

在 iOS 8 中以编程方式将视图中的按钮居中使用约束

iOS - 从 XIB 文件中引用和以编程方式移动视图

iOS9:在另一个以编程方式添加的视图中居中以编程方式添加的视图

iOS:以编程方式添加约束获取视图高度作为唯一指标