Frage

I have a menu that requires me to generate dynamically.

UIImageView *menu_item = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"menu_item"]];

[menu_item setFrame:CGRectMake(0, 0, 10, 30)];
[menu addSubview:menu_item];

[menu_item setFrame:CGRectMake(10, 0, 10, 30)];
[menu addSubview:menu_item];

[menu_item setFrame:CGRectMake(20, 0, 10, 30)];
[menu addSubview:menu_item];

where menu is a UIScrollView. Only the last menu_item is shown.

I know I can re-run initWithImage to make all 3 menu items appear, but is there a quicker way to clone the UIImageView?

Note: I know looping. Don't tell me the codes can be simplified via for-loop.

War es hilfreich?

Lösung

In your case you really don't need to worry about performance. UIImage imageNamed: has caching built into it to increase performance, and UIViews are very light weight.

If this menu could potentially have hundreds of items in it, then you should be using a UITableView or a UICollectionView instead of a UIScrollView. Their cell reuse is extremely efficient and easy to implement.

Andere Tipps

When I am not using a UITableView for navigation, I often use an array of dictionary items.

NSArray *navigationItems = @[
    @{@"DashboardViewController": @"Home"},
    @{@"DocumentsViewController": @"Documents"},
    @{@"IncidentViewController": @"Incidents"},
    @{@"HelpViewController": @"Help"},
    @{@"SettingsViewController": @"Settings"}
];

Then my layout code can loop through the array:

 //Create Naviation Elements
__block int containerViewHeight = 0;
__block NSString *navigationLabel;
__block NSString *navigationClass;
[navigationItems enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    navigationClass = [[obj allKeys] lastObject];
    navigationLabel = [[obj allValues] lastObject];

    UIButton *navigationButton = [UIButton buttonWithType:UIButtonTypeCustom];
    navigationButton.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    [navigationButton addTarget:self action:@selector(highlightButton:) forControlEvents:UIControlEventTouchDown];
    [navigationButton addTarget:self action:@selector(resetButton:) forControlEvents:UIControlEventTouchDragExit];
    [navigationButton addTarget:self action:@selector(loadNavigationController:) forControlEvents:UIControlEventTouchUpInside];
    [navigationButton setTitle:[navigationLabel uppercaseString] forState:UIControlStateNormal];
    [navigationButton setTitleColor:[UIColor navigationButtonFGColor] forState:UIControlStateNormal];
    [navigationButton.titleLabel setFont:[UIFont fontWithName:@"Eagle-Bold" size:20]];
    [navigationButton setBackgroundColor:[UIColor navigationButtonBGColor]]; //Didn't want to store in memory the original colour. So if you change this, change resetButton aswell.
    navigationButton.frame = CGRectMake(0, ((navigationItemHeight + kNavigationPadding) * idx) + (kNavigationPadding  * (idx + 1)), navigationMaxSize.width, navigationItemHeight);
    navigationButton.tag = idx;
    navigationButton.layer.cornerRadius = 3.0f;
    [navigationButton setExclusiveTouch:YES];

    [navigationView addSubview:navigationButton];

    //Add Height To Container View
    containerViewHeight += navigationItemHeight + (kNavigationPadding * 2);
}];

The button action goes into a method called -(void)loadNavigationController:(id)sender

  • I find out which button you clicked via the senders tag
  • I get the class view controller that you wanted to load as its the key of the dictionary
  • Then I push that view controller using [[NSClassFromString(className) alloc] init], (I also have check if the viewController you wish to load is already in the stack and pop instead.)

There is also a check to see if you want to override the default UIViewController alloc init. If the first key in the dictionary is a method name, it fires that instead.

//CustomFunction?
SEL customImplementation;
if([self respondsToSelector:(customImplementation = NSSelectorFromString(className))]){
    [self performSelector:customImplementation];     
    return;
}

In doing this i have been able to add and remove new navigation items with ease. This solution may not be everybody's cup of tea, and I definitely would recommend a table view.

Hopefully this may give you some ideas to help you in your situation. I have copied the code from a project of mine, apologies if i missed some ivars.

W

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top