Why can't I assign a view to a view?

Discussion in 'iOS Programming' started by dantastic, Jun 23, 2011.

  1. dantastic macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #1
    I have a an outlet to a UIView that is going to change pretty often so in order to be able to manage memory and everything I figured I'd be able to do the following:
    Code:
    @interface GalleryViewController : UIViewController {
        UIView *_infoView;
    }
    @property (nonatomic, retain) IBOutlet UIView *infoView;
    - (void) updateGalleryHeaderView;
    @end
    
    
    /////////// .m 
    
    - (void) galleryHeaderView {
        // So I'm not just adding more and more sub views.
        for (UIView *view in [self.infoView subviews]) {
            [view removeFromSuperview];
        }
        UIView *infoView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 30)];
        UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 5, 280, 25)];
        infoLabel.text = @"Some text";
        [infoView addSubview: infoLabel];
        self.infoView = infoView;           // <<<<< This doesn't work.
        // [self.infoView addSubview:infoView];  <<< This does work.
        [infoLabel release];
        [infoView release];
    }
    
    I though I should be able to assign infoView to self.infoView but this is not working. I can prove that everything is hooked up in IB by addming infoView as a subview to self.infoView.
    I don't like this approach as much though as it means I have to remove all the subviews before creating and adding a new subview.

    Should the above code work? If not, can someone please help me understand why not? I though I would be able to use this the same way as UITableViews tableHeaderView property.
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    What happens if you do:

    Code:
    [self setInfoView:infoView];
    
    ?

    Edit to add: in general I'd not call a variable within a method the same as an instance variable/property name.
     
  3. dantastic thread starter macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #3
    Code:
    [self setInfoView:infoView];
    didn't work either.

    The local variable will have to be renamed before I leave this piece to come back 3 months from now scratching my head wondering what I was thinking, agreed.
     
  4. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    That may well fix your problem. If it doesn't then I've got no real idea what's going on.
     
  5. nickculbertson macrumors regular

    nickculbertson

    Joined:
    Nov 19, 2010
    Location:
    Nashville, TN
    #5
    in your .h you posted
    Code:
    - (void) [COLOR="Red"]update[/COLOR]GalleryHeaderView;
    
    in your .m you have
    Code:
    - (void) galleryHeaderView 
     
  6. dantastic thread starter macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #6
    Yea, sorry bout that.. that was a halfway renaming. that's been sorted.


    So I've changed the local variable to 'UIView *paddingView =...' but still no luck. The new renamed view I can still add as a subview to self.infoView but I cannot assign it.
     
  7. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #7
    When you say "This doesn't work." what, exactly and in detail, is the issue. Do you get compiler warnings or errors? Is it something at runtime?

    Also you have neglected to post the synthesize directive or custom accessors you are using.
     
  8. dantastic thread starter macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #8
    I have a
    Code:
    @synthesize infoView = _infoView;
    Ok, when I say it doesn't work.
    In IB I have created a UIView with a yellow background. It's hooked up to 'infoView'.
    The UIview I'm creating programmatically has a green background color and a text label on top.

    When I do self.infoView = paddingView; the UIView remain yellow. If I would do the same to a UITableViews tableHeaderView property the view would assume that of the view I was assigning.

    there are no warnings or errors. Nothing is crashing or anything, I just get an unexpected result.
     
  9. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #9
    So infoView (or is that _infoView) is an IBOutlet? That's not what your code shows.

    Please post the actual, exact, copy and pasted code you are using.
     
  10. dantastic thread starter macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #10
    Code:
    #import <UIKit/UIKit.h>
    #import "Gallery.h"
    
    
    @interface GalleryViewController : UIViewController {
        Gallery *_gallery;
        UIImage *_newImage;
        UIView *_infoView;
        IBOutlet UIToolbar *_toolbar;
        IBOutlet UIBarButtonItem *_rightToolbarButton;
        IBOutlet UIBarButtonItem *_leftToolbarButton;
    }
    @property (nonatomic, retain) Gallery *gallery;
    @property (nonatomic, retain) UIImage *newImage;
    @property (nonatomic, retain) IBOutlet UIView *infoView;
    
    - (IBAction) toolbarButtonPressed:(id)sender;
    - (void) galleryHeaderView;
    
    @end
    
    ////////////// .m
    
    #import "GalleryViewController.h"
    #import "AppController.h"
    
    @implementation GalleryViewController
    
    @synthesize gallery = _gallery;
    @synthesize newImage = _newImage;
    @synthesize infoView = _infoView;
    
    - (void) galleryHeaderView {
        // Table header with number of active p/s/g in view.
        //for (UIView *view in [self.infoView subviews]) {
        //    [view removeFromSuperview];
        //}
        UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 30)];
        paddingView.backgroundColor = [UIColor greenColor];
        self.infoView = paddingView;
        //[self.infoView addSubview:paddingView];
        [paddingView release];
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        [self galleryHeaderView];
    }
    
    the galleryHeaderView you see there now is the exact version I'm trying with right now. I'm calling it from the viewDidLoad.
     
  11. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #11
    Where is infoView used? Simply assigning a new object to a variable/pointer will not cause any change in the view hierarchy (why would it). Where are you adding the new infoView to a view to display it?

    What I am getting at I assume the view with the yellow background (IB created) is visible (so is added as a subview of a visible view or window). You are setting the infoView property of this object to point at that view as an IBOutlet. This gives you a reference to the IB created view to modify it. This in no way links that property into the view hierarchy. The containing view or window is not watching this property for changes: you must remove the IB created view from it's superview then add the new view to it.
     
  12. dantastic thread starter macrumors 6502

    dantastic

    Joined:
    Jan 21, 2011
    #12
    Right, I see what you are saying.

    I thought I was being clever thinking my IBOutlet was essentially a placeholder and by using properties be able to handily swap out views using the setter and I would not have to think about cleaning out my subviews or any memory management.

    That's Ok, still learning. I already have a workaround in that I can add my view as a subview and just remove all subviews before doing so.

    cheers Robbie!
     
  13. MrGlassHalfFull macrumors newbie

    Joined:
    Jul 12, 2011
    #13
    Dan please PM me. I would love to talk to you!!
     

Share This Page