简体   繁体   English

在UIView addSubview期间克隆UIImageView

[英]Clone UIImageView during UIView addSubview

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 . menuUIScrollView Only the last menu_item is shown. 仅显示最后一个menu_item

I know I can re-run initWithImage to make all 3 menu items appear, but is there a quicker way to clone the UIImageView ? 我知道我可以重新运行initWithImage来显示所有3个菜单项,但是有没有一种更快的方法来克隆UIImageView

Note: I know looping. 注意:我知道循环。 Don't tell me the codes can be simplified via for-loop. 不要告诉我,可以通过for循环简化代码。

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. UIImage imageNamed:内置了缓存以提高性能,并且UIViews的重量很轻。

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. 如果此菜单中可能包含数百个项目,则应使用UITableView或UICollectionView而不是UIScrollView。 Their cell reuse is extremely efficient and easy to implement. 它们的单元复用非常高效且易于实现。

When I am not using a UITableView for navigation, I often use an array of dictionary items. 当我不使用UITableView进行导航时,我经常使用字典项数组。

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 该按钮动作进入一个称为-(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.) 然后,我使用[[NSClassFromString(className) alloc] init]推送该视图控制器(我还要检查您要加载的viewController是否已在堆栈中并弹出。)

There is also a check to see if you want to override the default UIViewController alloc init. 还有一个检查,看是否要覆盖默认的UIViewController分配初始化。 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 w ^

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM