简体   繁体   English

如何动态设置UIView的子视图(iPhone)?

[英]How to set subview of UIView dynamically (iPhone)?

I am surely doing something completely stupid here, hopefully someone can tell me what! 我肯定在这里做的事完全是愚蠢的,希望有人能告诉我什么! In summary I would like to programmatically toggle a subview when a button (I'll use a segmented button) is clicked. 总之,当单击按钮(我将使用分段按钮)时,我想以编程方式切换子视图。 It need not animate. 它不需要动画。 Ideally I'd load the contents of these views from a nib. 理想情况下,我将从笔尖加载这些视图的内容。

I am pushing a UIViewController subclass, initialised from a nib, on to a navigationController. 我正在将从笔尖初始化的UIViewController子类推到navigationController上。 This view controller & it's "default" view display ok. 此视图控制器及其“默认”视图显示正常。 This nib contains: 该笔尖包含:

File's Owner [Class=my view controller subclass]
First Responder
View
--Bar Segmented Control
--View //this is the 'subview' whose content I want to toggle

Perhaps I've made a mistake with my IB outlets? 也许我的IB分店弄错了吗? They are hooked up as follows: 它们的连接如下:

switchableView <--> View
view <--> View

And where switchableView is declared: 并在其中声明switchableView地方:

IBOutlet UIView *switchableView;
...
@property (nonatomic, retain)   UIView *switchableView;

I am stuck at replacing the contents of this UIView. 我停留在替换此UIView的内容。 First off, I just want to set it to a default when the view first comes to life. 首先,我只想在视图首次出现时将其设置为默认值。 Once I've got that, swapping it to something else should be easy as I can already capture the event generated by the segmented button. 一旦理解了这一点,将其交换到其他对象应该很容易,因为我已经可以捕获到由分段按钮生成的事件。 Can someone please tell me what I am doing wrong? 有人可以告诉我我做错了吗?

- (void)loadView {
NSLog(@"loadView invoked");
[super loadView];
UIView *view = [[UIView alloc] init];
UILabel *label = [[UILabel alloc] init];
label.text = @"Segment1";
[view addSubview:label];
[switchableView addSubview:view]; //this is what I can't work out
[view release];
[label release];    
}

That method is invoked (as is viewDidLoad ), but neither help. 该方法调用( viewDidLoad 被调用),但没有帮助。 I guess that I am doing [switchableView addSubview:view] wrong. 我猜我在[switchableView addSubview:view]做错了。 I've also tried switchableView = view , but a long time in the safety of Java and Perl makes me not 100% sure whether that is right to try or not! 我也尝试过switchableView = view ,但是长时间使用Java和Perl的安全性使我不能百分百确定是否正确!

Here's hoping someone can set me straight. 希望有人能让我直率。 Thanks in advance, 提前致谢,

Paul 保罗

Solved this in the end after inspecting the UICatalog sample code (with thanks to you both for giving me some pointers). 在检查了UICatalog示例代码后终于解决了这个问题(感谢你们俩给了我一些指导)。 The following works: 以下作品:

- (void)loadView {
    [super loadView];

    //define what will go in the seg1 view
    UILabel *mylabel = [[UILabel alloc] initWithFrame:switchableView.frame];
    mylabel.text=@"finally";
    self.seg1view = [[[UIView alloc] initWithFrame:switchableView.frame] autorelease];
    [self.seg1view addSubview:mylabel];
    [mylabel release];

    //define what will go in the seg2 view
    UILabel *mylabel2 = [[UILabel alloc] initWithFrame:switchableView.frame];
    mylabel2.text=@"it works!";
    self.seg2view = [[[UIView alloc] initWithFrame:switchableView.frame] autorelease];
    [self.seg2view addSubview:mylabel2];
    [mylabel2 release]; 

    //default the switchable view to seg1view
    [switchableView addSubview:self.seg1view];
}

-(void)doTheSwitch {
    if (segmentedButton.selectedSegmentIndex == 0) {
        [seg2view removeFromSuperview];
        [switchableView addSubview:seg1view];
    }
    if (segmentedButton.selectedSegmentIndex == 1) {    
        [seg1view removeFromSuperview];
        [switchableView addSubview:seg2view];
    }   
}

where the following are also defined as properties (retain, nonatomic) 其中以下内容也定义为属性(保留,非原子)

IBOutlet UIView *switchableView;
UIView  *seg1view;
UIView  *seg2view;

Here are some snippets to help you. 这里有一些片段可以帮助您。 The first is simply the initialization for a navigation controller 首先只是导航控制器的初始化

// In AppDelegate.m
-(void)applicationDidFinishLaunching:(UIApplication *)application
{
  // Create and configure the main view controller.
  UIViewController *firstViewController = [[UIViewController alloc] init];

  // Add create and configure the navigation controller.
  UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
  self.navController = navigationController;
  [navigationController release];

  // Configure and display the window.
  [window addSubview:navController.view];
  [window makeKeyAndVisible];
}

Then, when you're ready for a new view, just push one on there. 然后,当您准备好使用新视图时,只需将其推到该位置即可。

// Wherever you need to get your new view on there
UIViewController *secondViewController = [[UIViewController alloc] init];
[[self navigationController] pushViewController:secondViewController animated:YES];
[secondViewController release];

You should really be going through about 5 Apple Sample Projects a day in order to really become fluent in the iPhone world. 您真的应该每天进行大约5个Apple示例项目,以真正掌握iPhone世界。 Check out this one for starters: TableSearch . 查阅以下内容作为入门TableSearch

The most likely issue is that you are not setting the frame on your views, which means that while they are being successfully attached, they are 0x0 in size. 最可能的问题是您没有在视图上设置框架,这意味着在成功连接框架时,框架的大小为0x0。

Try something like: 尝试类似:

- (void)loadView {
  NSLog(@"loadView invoked");
  [super loadView];

  CGRect labelFrame = CGRectZero;
  labelFrame.size.height = switchableView.size.height;
  labelFrame.size.width = switchableView.size.width;

  UILabel *label = [[UILabel alloc] initWithFrame:labelFrame];
  label.text = @"Segment1";
  [switchableView addSubview:label]; //this is what I can't work out
  [label release];    
}

Also removed view because it was gratuitous (a UILabel is a UIView, you were stacking three view, 2 of which have nothing but a single subview which covers its full frame.) and it elided the UIViewController view property (in general it is bad to make local variables with the same name as instance variables or properties, there are compiler warnings you can turn on to avoid that). 还删除了视图,因为它是免费的(一个UILabel是一个UIView,您要堆叠三个视图,其中两个只有一个覆盖整个框架的子视图,什么也没有),并且它省略了UIViewController的view属性(通常,这样做很不好使用与实例变量或属性同名的局部变量,可以打开编译器警告来避免这种情况)。

If I understand your question correctly, you are trying to swap one view with another. 如果我正确理解了您的问题,则您正在尝试将一个视图与另一个视图交换。 One way to accomplish this is as follows: 实现此目的的一种方法如下:

Add an UIView to the root view named switchView. 将UIView添加到名为switchView的根视图中。 Either in code or in Interface Builder create a new UIView named subView1 and add it as a subclass of switchView when the root view loads: 在代码中或在Interface Builder中,创建一个名为subView1的新UIView并在根视图加载时将其添加为switchView的子类:

[switchView addSubview:subView1];

When the user toggles the segmented control in the root view, create a new UIView in a similar fashion named subView2 and switch it with the current subview of switchView: 当用户在根视图中切换分段控件时,以类似的方式创建一个名为subView2的新UIView,并使用switchView的当前子视图进行切换:

[subView1 removeFromSuperview];
[switchView addSubview:subView2];

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

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