0

While I can't post exact code (NDA), I can take the time to explain how it works design and implementation wise.

First off, all I'm doing currently is frontend stuff via producing static pages and writing events to be triggered.

A lot of the pages I've been writing have had very similar properties. These include:

  • The same background effect and image.
  • A navigation bar with a background, along with a title for the navigation bar reminding the user of what page they are currently on.
  • Additional Views for customization purposes.

Because of this, I decided to write my own custom ViewController which I felt the pages I write could inherit from. For the first two pages I wrote, everything worked as planned: all I had to do was inherit the class, specify my settings and the parent ViewController would take care of everything else in terms of rendering the desired template; the back button would display exactly where it was supposed to be, and when I pressed it, it would pop itself off the ViewController stack and simply go back to the home page.

It works something like this:

  • Parent class holds an NSMutableDictionary* (known as _additionalViews, which is @protected) and is initialized at the beginning of the page creation via [super initWithNibName] - which has an overloaded additional withNavTitle:(NSString*)navTitle parameter for the parent class as well as every child class of it.
  • Child class simply specifies the Views to create by adding those to the _additionalViews with relevant keys upon initialization. As soon as the viewDidLoad method is called, everything is loaded via iterating through _additionalViews by key and calling [self.view addSubview:[_additionalViews objectForKey:key]]
  • When the back button is pressed, the event for the object to pop itself off the viewController stack is managed and fired by the parent class, not the child.

As I'm sure you can see, this idea reduces a lot of code bloat and keeps things reusable. The first two pages I wrote with this methodology are basically static info pages, and the back button works perfectly with them (as well as the links to web pages and various other events I threw at them).

Now, however, when I create this new page, everything is rendered, but without any functionality. I'm doing everything in the same way that I did for the previous two pages. Why is this - how could this be?

What I can do is provide some utility functions that I've written for buttons and links and the like. If anyone sees anything in these that is probably not a good idea to have, I would really appreciate the feedback. They definitely render, and work for the first two pages. Just not this last one.

I appreciate the help (I've only been writing in Objective-C for 1.5 months now, so I'm still fairly new - I do however have a decent C++ background).

Code - Header and Source combined

#import <UIKit/UIKit.h>

typedef struct __TextAttributes__ {
    UIColor* textColor;
    bool isBold;
    CGFloat fontSize;
    NSString* text;

} TextAttributes;

typedef struct __ButtonAttributes__ {

    UIControlState  controlState;
    UIControlEvents controlEvents;
    NSString*       imgPath;
    id              target;
    SEL             selector;
} ButtonAttributes;

UITextView* UITextView_Make_NoEdit(NSString* displayText, CGFloat fontSize, bool useBoldFont, CGRect frameDims, UIColor* color, id delegate);

UIButton* Link_Make(NSString* linkText, CGFloat fontSize, bool useBoldFont, 
                    SEL actionSelector, id target, CGRect frameDims);

UIButton* Button_Make_Custom(TextAttributes* ta, ButtonAttributes* attr, CGRect frameDims, bool freeBtnAttr, bool freeTextAttr);

ButtonAttributes* ButtonAttributes_Make(NSString*imgName, NSString* imgType, UIControlState controlState, UIControlEvents controlEvents, id target, SEL selector);

void ButtonAttributes_Free(ButtonAttributes* attr);

TextAttributes* TextAttributes_Make(NSString* text, UIColor* textColor, CGFloat fontSize, bool isBold);

void TextAttributes_Free(TextAttributes* attr);

//-------------------
// Global Functions  
//-------------------

//----------------------------------------
static const float TextFont_Alpha = 0.75;
//----------------------------------------

typedef enum __MemoryType__ {
    MemoryTypeTextAttributes,
    MemoryTypeButtonAttributes
} MemoryType;

static void CheckMemAndThrow(void* mem, MemoryType mt )
{
    if (mem)
        return;

    NSString *memTypeAndFunc, *msg;

    switch (mt) {
        case MemoryTypeButtonAttributes:
            memTypeAndFunc = @"ButtonAttributes in ButtonAttributes_Make(...)";
            break;
        case MemoryTypeTextAttributes:
            memTypeAndFunc = @"TextAttributes in TextAttributes_Make(...)";
            break;
    }

    msg = [NSString stringWithFormat:@"Memory allocation error for %@", [memTypeAndFunc autorelease]];

    @throw [[NSException alloc] initWithName:@"MemoryAllocException" reason:msg userInfo:nil];
}

UITextView* UITextView_Make_NoEdit(NSString* displayText, CGFloat fontSize, bool useBoldFont, CGRect frameDims, UIColor* color, id delegate) 
{
    UITextView* view = [[UITextView alloc] initWithFrame:frameDims];

    [view setText:displayText];

    UIFont* font;

    if (useBoldFont)
    {
        font = [UIFont boldSystemFontOfSize:fontSize];
    }
    else 
    {
        font = [UIFont systemFontOfSize:fontSize];
    }

    [view setTextColor:color];
    [view setDelegate:delegate];
    [view setEditable:NO];
    [view setScrollEnabled:NO];
    [view setBackgroundColor:[UIColor clearColor]];
    [view setFont:font];
    [font release]; 

    return view;
}

static const CGFloat Default_Link_Red   = 1.0f / 255.0f;
static const CGFloat Default_Link_Green = 184.0f / 255.0f;
static const CGFloat Default_Link_Blue  = 252.0f / 255.0f;
static const CGFloat Default_Link_Alpha = 1.0f;

UIButton* Link_Make(NSString* linkText, 
                    CGFloat fontSize, 
                    bool useBoldFont, 
                    SEL actionSelector, id target, 
                    CGRect frameDims) 
{
    UIButton* linkButton = [UIButton buttonWithType:UIButtonTypeCustom]; 


    [linkButton setFrame:frameDims];

    [linkButton setTitleColor:[UIColor colorWithRed:Default_Link_Red 
                                              green:Default_Link_Green 
                                               blue:Default_Link_Blue 
                                              alpha:Default_Link_Alpha] 

                     forState:UIControlStateNormal];

    [linkButton setTitle:linkText forState:UIControlStateNormal];

    UIFont* font;

    if (useBoldFont) 
    {
        font = [UIFont boldSystemFontOfSize:fontSize];
    } 
    else 
    {
        font = [UIFont systemFontOfSize:fontSize];
    }

    [linkButton.titleLabel setFont:[font retain]];

    [linkButton addTarget:target action:actionSelector forControlEvents:UIControlEventTouchDown];

    [font release];

    return linkButton;
}

UIButton* Button_Make_Custom(TextAttributes* attr, ButtonAttributes* buttonAttr, CGRect frameDims, bool freeBtnAttr, bool freeTextAttr)
{

    UIButton* btn = [UIButton buttonWithType:UIButtonTypeCustom];

    [btn setTitle:attr->text forState:buttonAttr->controlState];
    [btn setTitleColor:attr->textColor forState:buttonAttr->controlState];
    [btn setBackgroundColor:[UIColor clearColor]];

     if (attr->isBold) 
     {
         [btn.titleLabel setFont:[UIFont boldSystemFontOfSize:attr->fontSize]];
     } 
     else 
     {
         [btn.titleLabel setFont:[UIFont systemFontOfSize:attr->fontSize]];
     }

    [btn setFrame:frameDims];

    [btn setBackgroundImage:[UIImage imageWithContentsOfFile:[buttonAttr->imgPath retain]] forState:buttonAttr->controlState];

    [btn addTarget:buttonAttr->target 
            action:buttonAttr->selector 
  forControlEvents:buttonAttr->controlEvents];

    if (freeTextAttr)
        TextAttributes_Free(attr);

    if (freeBtnAttr)
        ButtonAttributes_Free(buttonAttr);

    if (![btn isEnabled])
        [btn setEnabled:YES];

    return btn;
}

ButtonAttributes* ButtonAttributes_Make(NSString* imgName, NSString* imgType, UIControlState controlState, UIControlEvents controlEvents, id target, SEL selector) 
{
    ButtonAttributes* btnAttr = (ButtonAttributes *)calloc(1, sizeof(ButtonAttributes));

    CheckMemAndThrow((void*)btnAttr, MemoryTypeButtonAttributes);

    btnAttr->imgPath       = [[NSBundle mainBundle] pathForResource:imgName ofType:imgType];
    btnAttr->controlState  = controlState; 
    btnAttr->controlEvents = controlEvents;
    btnAttr->target        = target;
    btnAttr->selector      = selector;

    return btnAttr;
}

void ButtonAttributes_Free(ButtonAttributes* attr)
{
    if (!attr)
        return; 

    if (attr->imgPath)
        [attr->imgPath release];

    free(attr);
}

TextAttributes* TextAttributes_Make(NSString* text, UIColor* textColor, CGFloat fontSize, bool isBold)
{
    TextAttributes* textAttributes = (TextAttributes *)calloc(1, sizeof(TextAttributes));

    CheckMemAndThrow((void*)textAttributes, MemoryTypeTextAttributes);

    textAttributes->text      = text;
    textAttributes->textColor = textColor;
    textAttributes->fontSize  = fontSize;
    textAttributes->isBold    = isBold;

    return textAttributes;
}

void TextAttributes_Free(TextAttributes* attr)
{
    if (!attr)
        return;

    if (attr->text) {
        [attr->text release];
    }

    if (attr->textColor) {
        [attr->textColor release];
    }

    free(attr);
}
zeboidlund
  • 9,731
  • 31
  • 118
  • 180
  • The only thing that looks odd to me is the use of `UIControlEventTouchDown` for a button, which 99% of the time takes `UIControlEventTouchUpInside`. I doubt that makes a difference though. In the code where you set the target and action for the back button, does anything happen differently when you step through it in the debugger? `nil` or wrong selector or target or something perhaps? That would be where I'd start. – Carl Veazey Sep 05 '12 at 02:54
  • Still intrigued about this one, were you ever able to come to a resolution? – Carl Veazey Sep 11 '12 at 22:49
  • I did come up with a fix, but I can't remember for the life of me what it was. Sorry. I was just doing an internship and I wound up finishing it the day after I posted this I think. – zeboidlund Sep 11 '12 at 23:35
  • If I remember correctly, it was something awfully stupid that I did. – zeboidlund Sep 11 '12 at 23:36

0 Answers0