Developer Examples for Implementing Buttons W/O using Interface Builer/StoryBoard?

Discussion in 'iOS Programming' started by TwinofSian, Jul 7, 2012.

  1. TwinofSian macrumors member

    Joined:
    Oct 23, 2011
    #1
    I am interested in delving more into the apple developer code on their website, but I notice they constantly use interface builder/story board to implement all their buttons. Because of the constant changing nature of Xcode & iOS I think this is not the most stable way to understand how a UI is actually implemented.

    I have noticed that using interface builder automatically inserts certain code into Xcode and then the developer declares whatever other declarations he intended to.

    Is there any good example code you guys recommend for learning how to implement interface buttons without using Interface Builder or Story board?
     
  2. jnoxx macrumors 65816

    jnoxx

    Joined:
    Dec 29, 2010
    Location:
    Aartselaar // Antwerp // Belgium
    #2
    Code:
    UIButton *button = [UIButton buttonWithType:(insertTypehere)];
    [button setFrame:CGRectMake(0,0,100,100)];
    [self.view addSubview:button];
    
    typed this out of my head, so just try it :)
    This basically goes for all IB elements and so on. do it all by code that is.
     
  3. firewood macrumors 604

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #3
    Apple has a Catalog sample app which creates almost every type of button and other UI element in code, no IB needed.

    IB inserts no code. It inserts data (button positions, colors, etc.). The UI controllers already have all the code needed already built-in to deal with the data with which they are initialized (nibs from IB, etc.)

    This has the huge advantage that you can move stuff around in IB, and IB does NOT mess with your code (how you arranged it, formatted it, etc.)
     
  4. TwinofSian, Jul 9, 2012
    Last edited: Jul 9, 2012

    TwinofSian thread starter macrumors member

    Joined:
    Oct 23, 2011
    #4
    Thanks for the tip, definitely gives me a better idea of how to handle this...
    FYI, I put it in one of the -(IBAction) Click1 methods, and I got two errors related to this statement:

    Code:
    (insertTypehere) is undeclared
    request for member 'view' in something not a structure or union
    
    I fixed one error by saying self.window (window is an instance of UIWindow which is an ivar of the App delegate--this is a super noob tutorial I am running thru) but I am a little confused on how to handle the other one.

    edit: I looked up the definition of buttonWithType and it doesn't seem to take an argument--what else am I missing here?
     
  5. jnoxx macrumors 65816

    jnoxx

    Joined:
    Dec 29, 2010
    Location:
    Aartselaar // Antwerp // Belgium
    #5
    Oh my, you're kinda new right?
    What I meant with the insertTypehere, is that you had to specifically type in the Type you want from button (the ones provided in the SDK).
    If you command clicked on that method or went to the documentation via Xcode on that command I showed you, it would've shown you this:
    Click me

    Here you can see the different types of buttons at UIButtonType:
    So all you needed to do was basically type in one of these:
    Code:
    typedef enum {
       UIButtonTypeCustom = 0,
       UIButtonTypeRoundedRect,
       UIButtonTypeDetailDisclosure,
       UIButtonTypeInfoLight,
       UIButtonTypeInfoDark,
       UIButtonTypeContactAdd,
    } UIButtonType;
    so if you do this -> UIButtonTypeRoundedRect instead of (insertTypeHere), it should work..
     
  6. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #6
    When referencing an external resource, it is a common courtesy to provide as much detail about that resource as possible. For a book, that would be title, author, edition, chapter, and page number. For an online tutorial, that would be a URL and any other relevant information. So, what tutorial are you running through?
     
  7. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #7
    Where did you look it up?

    The class reference shows +buttonWithType: under the "Creating Buttons" heading, and it does take an argument.
     
  8. TwinofSian thread starter macrumors member

    Joined:
    Oct 23, 2011
    #8
    I apologize, the tutorial is a refresh for me--I haven't been coding lately and am getting back into Objc-C. I am using Kochan's brilliant book "Programming in Objective-C" Chapter 21 tutorial on making a very simple iphone app.

    I have completed this tutorial before, but I am trying to figure out how to create all the buttons and labels without using interface builder.
     
  9. jnoxx macrumors 65816

    jnoxx

    Joined:
    Dec 29, 2010
    Location:
    Aartselaar // Antwerp // Belgium
    #9
    Didn't I just showed you code how to do that? (no offense, just wandering what I did wrong.. So I know what to improve to further postings).
     
  10. TwinofSian thread starter macrumors member

    Joined:
    Oct 23, 2011
    #10
    You did. I was responding to the other contributor.

    Right now however, the code isn't working out.

    I had Used the interface builder to set the iPhone window background to black, but when I typed in the code below, the simulator launches successfully, but no button apears--it's just a black window. Here's my code:

    Code:
    AppDelegate_iPhone.m
    -(IBAction) click1: (id) sender
    {
    	[display setText:@"1"];
    	UIButton *button1 = [UIButton buttonWithType: UIButtonTypeRoundedRect];
    	[button1 setFrame:CGRectMake(90,60,100,100)];
    	
    	[self.window addSubview:button1];
    	
    }
     
  11. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #11
    You should be adding the button in the viewController code and not the appDelegate.
     
  12. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #12
    Step 1: Start with a working example.
    Step 2: Confirm it works as-is.
    Step 3: Study it to understand how it works.
    Step 4: Modify it, adapt it, or extract portions of it for other uses.

    The approach you're using now is to start from nothing, add random untested code fragments, and try to figure out what's not working. This is rarely effective.
     
  13. TwinofSian thread starter macrumors member

    Joined:
    Oct 23, 2011
    #13
    Normally that is exactly what I would do. Because I am following Kochan's tutorial, we chose the Window Based Application template which does not have a ViewController class.

    I wanted to see how I could duplicate the author's instructions without using the interface builder.
     
  14. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
  15. TwinofSian thread starter macrumors member

    Joined:
    Oct 23, 2011
    #15
    It's supposed to be called, when the user presses the button labeled 1.

    I haven't set up any label or button in the interface builder. How do I set up this call without using IB?
     
  16. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #16
    So, is your intent to have button1 added to the view in response to clicking "the button labeled 1"? Or, are you wanting your button1 to be in the view the whole time? If the latter, consider a different place to add it as a subview, say in your viewDidLoad. Also, what is display?
     
  17. TwinofSian thread starter macrumors member

    Joined:
    Oct 23, 2011
    #17
    I'd like button 1 to be viewed the entire time.

    'display' is an instance of UILabel and an instance variable of App Delegate.
     
  18. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #18
    Then it doesn't really make sense to add it to the subview in response to clicking it, does it? How can you click a button that hasn't appeared yet?

    And where have you added display as a subview?

    In conclusion, if you are wanting to replace IB functionality with code, you need to think hard about and/or learn what (and when) IB is doing for you "behind the scenes". For example, when you connect a button with an IBAction in IB, what do you think is taking place, if it were code, and where would that happen?
     
  19. TwinofSian thread starter macrumors member

    Joined:
    Oct 23, 2011
    #19
    As far as I know, I haven't added display as a subview any where.

    Here's what is tripping me up: I get the the -(IBAction) click1 needs to have a button attached to it, and that it is meant to call main which then calls the label and draws "1" on it like any proper calc app should.

    I will consult the apple catalog example when I wake up tomorrow, but in the mean time, for the sake of clarity, what is tripping me up is how I actually tell Xcode to draw a button without using IB.

    Specifically, do I draw the button with a method in AppDelegate? Class Method or Instance? Will it be void, or am I asking it to return some obscure class instance?

    Thanks.
     
  20. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #20
    Well, you'll have to address that issue at some point, too, then. But let's not get ahead of ourselves...

    Well, you've already been given the code to add the button; it's just a matter of putting that code in the right place.

    Here's a tutorial that may help, although you'll have to adapt it from using Cocoa (e.g. it uses NSButton) to using Cocoa Touch (e.g. you'll want to us UIButton):
    http://www.wmdeveloper.com/2010/07/cocoa-how-to-create-buttons-without.html

    I still find it strange that a Kochan tutorial doesn't ask you to create a UIViewController subclass. I'm currently "between" editions of his book so I can't look up the specifics of this chapter to give you more guidance.
     
  21. TwinofSian thread starter macrumors member

    Joined:
    Oct 23, 2011
    #21
    Thanks immensely for the link.

    Although, when trying to implement this button, I get six errors.

    Code:
    CGRect frame = CGMakeRect(10, 40, 90, 40);
        UIButton* pushButton = [[UIButton alloc] initWithFrame: frame];
        pushButton.bezelStyle = CGRoundedBezelStyle;
        [self.window.contentView addSubview: pushButton];
        
        pushButton.target = self;
        pushButton.action = @selector(buttonClicked:);


    CGRectMake: invalid initializer

    pushButton.bezelStyle = CGRoundedBezelStyle request for member

    'bezelStyle' in something not a structure or union

    'CGRoundedBezelStyle' undeclared (first use in this function)


    request for member 'contentView' in something not a structure or union


    error: request for member 'target' in something not a structure or union

    request for member 'action' in something not a structure or union


    is 'pushButton' a property I have to declare?
     
  22. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #22
    You can't just change the class from NSButton to UIButton and have it work. You have to understand what the original code is doing, and write new code that does the equivalent. Or if there isn't an equivalent, you have to eliminate code or rework it to do something sensible.

    You've missed an important fact: An NSButton has a bezel, but a UIButton doesn't.

    So the first step to doing a conversion is to learn what a bezel is and figure out an equivalent (if there is one). If you don't have the knowledge of NSButton and UIButton to do that, then you're wasting your time trying to convert an unsuitable tutorial into a suitable one. Doing so would require you to already have the very knowledge you're trying to obtain from the tutorial. That is, you'd have to already know what the tutorial is teaching, and know it well enough to make the conversions.

    You'll be far better off with something that already uses the Cocoa Touch classes (e.g. UIButton etc.). Apple's sample code for that was already mentioned much earlier in this thread. Its name is UICatalog. Its description is:
    This sample is a catalog exhibiting many views and controls in the UIKit framework, along with their various properties and styles.

    If you need code to create specific UI controls or views, refer to this sample and it should give you a good head start in building your user interface. In most cases you can simply copy and paste the code snippets you need.

    When images or custom views are used, accessibility code has been added. Using the iPhone Accessibility API enhances the user experience of VoiceOver users.
     
  23. xArtx macrumors 6502a

    Joined:
    Mar 30, 2012
    #23
    Code:
        CGRect infrectangle = CGRectMake(255,420,50,50);
        CGContextAddEllipseInRect(context, infrectangle);
        CGContextFillPath(context);
        CGContextAddEllipseInRect(context, infrectangle);
        CGContextStrokePath(context);
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
        [self coordsForTouch:[touches anyObject]];
        [self setNeedsDisplay];
    }
     
    - (void)coordsForTouch:(UITouch *)touch {
    
        CGPoint tp = [touch locationInView:self];
        
        if (tp.x > 75) {
        if (tp.x < 125) {
        if (tp.y > 420) {
        buttonpressed = 1;
        }}}
    }
    
     
  24. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #24
    Nobody has addressed the premise of your post - that hard-coding UI objects is going to make your code more "future-proof" than using interface builder and/or storyboards.

    I think your assumption is wrong, and completely backwards. Using IB and/or storyboards will be better than building your view objects in code. If Apple updates some view objects, or adds new interface features (like constraints instead of struts and springs, for example) it will be far, far easier to update your code if you use interface builder than if you hard-code your objects.

    New iOS developers seem to not like using IB, and think it's better to hard-code everything. That is wrong. Hard-coding everything is a nightmare.

    It's a useful exercise to learn how to handle all the settings yourself, but for production code, maintaining hard-coded interfaces is a nightmare.
     
  25. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #25
    Another big reason for not hard-coding views is Internationalization and Localization. Different human languages use different amounts of space, and also have different conventions of "natural reading order". If views are managed entirely in code, every additional language or other localization changes requires modifying the code.

    Even something as simple as changing from American English to British English could affect layouts if the text happens to contain a word like "Color" that needs to be changed to "Colour".
     

Share This Page