【问题标题】:Two views Multiple UIPickerViews Single outlet两个视图 多个 UIPickerViews 单个出口
【发布时间】:2011-07-15 08:23:29
【问题描述】:

我的应用程序有两个视图,具体取决于它决定加载哪个视图的方向。但是 IB 不允许我将两个 PickerView 连接到同一个 OUTLET,有没有办法在代码中分配连接,以便在加载视图时将连接分配给插座?

或者我应该为每个视图都加倍?

或者我应该将我的两个视图拆分为不同的 nib 文件

请帮帮我

谢谢

【问题讨论】:

    标签: iphone objective-c ios ipad


    【解决方案1】:

    请记住,IBOutlet 只是一个属性,它以一种使其在 IB 中可见的方式被声明。所以你的第一个问题的答案是肯定的。如有必要,您始终可以在代码中重新分配该属性。

    我假设您已经有两个 IBOutlets 用于您的横向和纵向视图 - 像这样:

    @property (nonatomic, retain) IBOutlet UIView *landscapeView;
    @property (nonatomic, retain) IBOutlet UIView *portraitView;
    

    听起来您正在willAnimateRotationToInterfaceOrientation:duration: 中选择合适的视图。

    同样,您可以为您的选择器视图声明两个出口:

    @property (nonatomic, retain) IBOutlet UIPickerView *landscapePickerView;
    @property (nonatomic, retain) IBOutlet UIPickerView *portraitPickerView;
    

    如果你走这条路,我会声明一个动态属性,它总是返回当前方向的选择器视图。

    @property (nonatomic, retain, readonly) UIPickerView *pickerView;
    

    您可以像这样实现它,而不是合成这个属性:

    - (UIPickerView *) pickerView {
        if (self.landscapeView.superview) {
            return self.landscapePickerView;
        }
        else {
            return self.portraitPickerView;
        }
    }
    

    但是,如果您有不止一个或两个子视图,那么像这样的并行属性会使您的控制器混乱不堪。在这种情况下,我会考虑创建一个 UIView 的自定义子类,称为 PickerContainer 之类的东西,它为您的 pickerView 和您需要访问的任何其他子视图提供出口。然后在 IB 中,您可以将横向和纵向视图的类更改为 PickerContainer,并且您可以将每个选择器直接连接到其父视图。然后在您的控制器中,您可以像这样创建一个动态属性:

    @property (nonatomic, retain, readonly) PickerContainer *pickerContainer;
    
    - (PickerContainer *)pickerContainer {
        return (PickerContainer *)self.view;
    }
    

    之后,您可以通过它的容器访问您的 pickerView 以获取当前方向,如下所示:

    [self.pickerContainer.pickerView reloadAllComponents];
    

    编辑:这是我在我的一个项目中实施willAnimateRotationToInterfaceOrientation:duration: 的方式:

    - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
        if (UIInterfaceOrientationIsPortrait(interfaceOrientation)) {
            if (self.landscapeView.superview) [self.landscapeView removeFromSuperview];
            self.portraitView.center = CGPointMake(self.view.bounds.size.width / 2,
                                                   self.view.bounds.size.height / 2);
            [self.view addSubview:self.portraitView];
        }
        else {
            if (self.portraitView.superview) [self.portraitView removeFromSuperview];
            self.landscapeView.center = CGPointMake(self.view.bounds.size.width / 2,
                                                    self.view.bounds.size.height / 2);
            [self.view addSubview:self.landscapeView];
        }
    }
    

    我的横向和纵向视图在 IB 中配置为没有支柱或弹簧,这意味着所有边距都是灵活的,但宽度和高度不是。

    【讨论】:

    • 我按照你的建议做了。但是现在当我想加载这个视图时,它会冻结,然后在我的 shouldAutorotateToInterfaceOrientation 中给我一个异常 EXC_BAD_ACCESS。我使用的代码是: - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { if(UIInterfaceOrientationIsLandscape(self.interfaceOrientation)){ self.view = LandscapeView; } if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){ self.view = portraintView; } 返回是; }
    • 不要在shouldAutorotateToInterfaceOrientation: 中交换视图。该方法除了返回 YES 之外什么都不做。相反,交换- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 中的视图,并将条件基于其toInterfaceOrientation 参数。
    • 对不起...我实际上是想告诉你交换- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration中的观点。我把那些搞混了。我将在上面编辑我的答案。
    • - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrient‌​ation duration:(NSTimeInterval)duration 当我将此方法粘贴到我的代码中时,它会显示预期方法主体,即使我确实添加了实现,- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfac‌​eOrientation duration:(NSTimeInterval)duration 也是如此
    • 没关系,我发现了那个方法的问题,现在我发生了一些非常奇怪的事情,当我改变方向时它会加载相反的视图,例如当我更改为横向时它会加载横向但显示纵向?知道为什么会这样
    【解决方案2】:

    我最近在我的应用程序中应用了这个概念。在这种情况下,您可以为每个在触摸时显示选择器的按钮分配一个 int
    假设您有两个按钮 btn1 和 btn2。让他们的触摸动作是btn1Actionbtn2Action。您还可以为两个选择器使用一个工具栏。将选择器和工具栏的可见性设置为隐藏在 xib 中。

    -(void)btn1Action:(id)sender
    {
    picker.setHidden = NO;
    toolbar.setHidden = NO;
    iPicker = 1;          // Declared globally
    }  
    
    -(void)btn2Action:(id)sender
    {
    picker.setHidden = NO;
    toolbar.setHidden = NO;
    iPicker = 2;          // Declared globally
    }  
    
    -(void)toolbarAction:(id)sender
    {
    picker.setHidden = YES;
    toolbar.setHidden = YES;
    }
    
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
    {
    
    
    
         if(iPicker==1)
        {
          return 10;
        }
         if(iPicker == 2)
        {
            return 8;
        }
    
    
    }
    
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
    {
    
        return 1;
    }
    - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)iComponent
    {
    
         if(iPicker==1)
        {
       // Your code
    
       }
        else if(iPicker == 2)
        {
            // Your code
        }
    
    
    }
    
    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)iComponent
    {
    
        else if(iPicker == 1)
        {
             // Your code
    
        }
        else if (iPicker == 2)
        {
            // Your code
        }
        } 
    

    希望这会有所帮助。

    【讨论】:

    • 上面的代码仍然可以通过为按钮分配标签来最小化,然后您可以进行单个操作。 -(void)buttonAction:(id)sender { picker.setHidden = NO; toolbar.setHidden = NO; iPicker = sender.tag; // Declared globally }
    猜你喜欢
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    相关资源
    最近更新 更多