0

I've got a default layout in my storyboard for a specific view controller. I'd like to add a few things programmatically, but I'm not sure how to go about it so that it adjusts the layout for my other views.

Since I just drag and drop things in to the layout, there's no clear structure (Layouts within layouts, relativity, etc) like in android.

For example, I want to be able to click on a view, and expand a chart below that view, pushing down every view underneath the expanded view.

At the moment, I can add a view at a specific place in my layout, but it'll be behind the other views unless there isn't anything in front of it to be behind.

So I guess I'm asking if I can do most of the layout in the storyboard and give them some sort of the structure via that way, and then add things programmatically between items.

OR

Should I just do everything programmatically? That'd take some reworking on my part since everything's already in my storyboard in terms of interaction between my view controllers and stuff.

Thanks!

Gentatsu
  • 696
  • 1
  • 6
  • 26

3 Answers3

0

You should structure your Views properly in Interface Builder, you can use constraints to do so. Of course you can add views programmatically as well. Remember that Interface Builder does nothing else then defining a file which stores the structure of your interface to load it from nib. So you just need to add your views programmatically using addSubview methods and add your constraints just the same way in code.

These methods might come in handy to update your view:

[self.view setNeedsLayout];
[self.view setNeedsUpdateConstraints];
[self.view setNeedsDisplay];
iCaramba
  • 2,589
  • 16
  • 31
0

The answer is "of course". The Storyboard is here only to place the elements that will always be displayed. After, if you want to make some views that appear and disappear, you'll have to do it programmatically ;) And it's really simple

Look at this, the method Notepad is an IBAction, when i click on a button created in the Storyboard.

- (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;
                         }];
    }
}

EDIT : Don't judge me ^^ I wrote this when I was learning Obj-C! It's just to show you that you can create fields programmatically when you hit an item from Storyboard

Verdant
  • 288
  • 1
  • 10
  • Does this shift around the views around it, though? I know I can add/remove them, but it's mainly how the other views in the default storyboard are shifted when I add a view programmatically. – Gentatsu Nov 25 '14 at 17:30
  • Not it doesn't. The views won't move, or you'll have to do it by yourself. Subviews have a hierarchy. They are not on the same plane, then why a subviews would move? ^^ – Verdant Nov 25 '14 at 17:32
  • That's essentially what I'd like to know would work. If I click something in the middle of my page, I want it to expand from the middle and display something under the thing I clicked whilst pushing everything that was below the thing I clicked now under the expanded item. – Gentatsu Nov 25 '14 at 17:37
  • Then, you'll have to animate all the view by yourself. Don't forget that you can do it, easily, but it will be an optical illusion for the user ^^ You want to do the same effect that when you open the menu in Facebook App, but from the middle of the screen? (for exemple ofc). Am I right? – Verdant Nov 25 '14 at 17:39
  • Lol, yeah, that's what my question was regarding to. If it was possible to do it using a mixture. I don't think so. More so, if you were to click on an option, and then more stuff comes underneath. Like if you were to click on a stock value, a chart shows underneath it showing the trends. I'm doing something similar to that. – Gentatsu Nov 25 '14 at 17:53
  • In android, you set your layout in XML and then you can insert things in a certain point. If you have your point of entry inside a "LinearLayout", you can append it on the end of the views inside that layout and it'll just add it to the bottom or right depending on the orientation. I thought I could do something similar with this. – Gentatsu Nov 25 '14 at 17:54
  • Have you an exemple to show me exactly what you want to reproduce? I don't understand everything ^^' (i'm french) – Verdant Nov 25 '14 at 18:01
  • Like this: http://jackkwok.github.io/JKExpandTableView/ but with generic views, not just tables. – Gentatsu Nov 25 '14 at 18:05
-1

If your view is laid out in xib file then you can add views programatically on top of interface created from xib file. by making views and adding/hiding them using addSubview(myCustomView) and myCustomView.isHidden = true. Just keep in mind to also add contraints after adding the subviews.