UIView 仅在第二次调用后显示

Posted

技术标签:

【中文标题】UIView 仅在第二次调用后显示【英文标题】:UIView only shows after being called the second time 【发布时间】:2013-12-12 16:14:41 【问题描述】:

我有一个视图控制器,它通过 IBAction 调用自定义 UIView。自定义视图包含一个从屏幕底部向上滑动的 UIPickerView 和一个带有“取消”和“完成”按钮的工具栏。问题是视图只出现在屏幕上第二次调用后。使用断点,我可以验证每一行代码都被调用了两次。一切似乎每次都以同样的方式发生。没有什么是 NIL,事实上,在应用程序运行期间它就是这样,而不仅仅是第一次调用它。只要应用程序正在运行,您总是必须单击该按钮两次才能显示视图。

诚然,自定义选择器视图的代码不是我的。我从别人的例子中复制了它。我不确定这是否是问题所在。我不明白怎么可能,但我在这里有点过头了。这就是我从视图控制器调用视图的方式。

- (IBAction)statusPickerButtonPressed:(id)sender 

self.scrollPickerView = [[StatusPickerView alloc]init];

[self.navigationController.view addSubview:self.scrollPickerView];
self.scrollPickerView.delegate = self;
self.scrollPickerView.dataSource = self;

这是自定义 UIView

#import "StatusPickerView.h"

@interface StatusPickerView ()
@property NSArray *pickerArray;
@property NSInteger selectedRow;
@end

@implementation StatusPickerView


- (id)initWithFrame:(CGRect)frame

self = [super initWithFrame:frame];
if (self) 
    [self setToolbar];
    [self becomeFirstResponder];


    float screenWidth = [UIScreen mainScreen].bounds.size.width;
    float pickerWidth = screenWidth * 3 / 4;
    float xPoint = screenWidth / 2 - pickerWidth / 2;



    [self setFrame: CGRectMake(xPoint, 50.0f, pickerWidth, 180.0f)];
    self.showsSelectionIndicator = YES;
    [self selectRow:3 inComponent:0 animated:YES];



return self;




-(void)setToolbar

_toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[_toolbar setBarStyle:UIBarStyleDefault];

UIBarButtonItem * btnCancel = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
                                                                            target:self action:@selector(barbtnPressed:)];
UIBarButtonItem * flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
                                                                          target:nil action:nil];
UIBarButtonItem * btnDone = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
                                                                          target:self action:@selector(barbtnPressed:)];
[btnCancel setTag:1];
[btnCancel setStyle:UIBarButtonItemStyleBordered];

[btnDone setTag:2];
[btnDone setStyle:UIBarButtonItemStyleBordered];

NSArray * btnArray = [[NSArray alloc] initWithObjects:btnCancel, flexible, btnDone, nil];
[_toolbar setItems:btnArray];

self.inputAccessoryView = _toolbar;
self.inputView = self;


-(BOOL)canBecomeFirstResponder

return true;





-(void)barbtnPressed:(id)sender

NSInteger tag = [sender tag];
switch (tag) 
    case 1:
    
        [self removeFromSuperview];
        break;
    
    case 2:
        [self removeFromSuperview];
        self.selectedRow = [self selectedRowInComponent:0];
        [[NSNotificationCenter defaultCenter]postNotificationName:@"user_selected_new_section" object:self];

    
    default:
        break;



-(int)giveSelectedRow

return self.selectedRow; 

我完全准备好在这里感到愚蠢,因为解决方案可能很明显,但对我自己来说并不明显。

编辑: 我尝试使用[self.view.window addSubview:self.scrollPickerView]; 而不是[self.navigationController.view addSubview:self.scrollPickerView];,行为完全一样。

【问题讨论】:

[self.navigationController.view addSubview:self.scrollPickerView];这个链接不正确。以及为什么您只在第二次按下时才查看显示.. mb RunLoop 重绘屏幕? 你能解释一下它是如何不正确的吗?正确的方法应该是什么? self.navigationController 有 2 个子视图。您可以在 Apple 文档developer.apple.com/library/ios/documentation/UIKit/Reference/… 中阅读相关内容,并且您不需要添加更多子视图。 StatusPickerView 是什么的子类?你能贴出让它向上滑动的代码吗? 其次..StatusPickerView 奇怪的视图。阅读此developer.apple.com/LIBRARY/IOS/documentation/UIKit/Reference/… 【参考方案1】:

这一行:

 [self.navigationController.view addSubview:self.scrollPickerView];

应改为:

 [self.view addSubview:self.scrollPickerView];

【讨论】:

我试过了,还是一样。我还在控制台“设置表格的第一响应者视图但我们不知道它的类型(单元格/页眉/页脚)”中收到此警告。【参考方案2】:

您调用的是-init 而不是-initWithFrame:,因此您的视图以CGRectZero 的默认框架结束。考虑到您正在制作自己的框架,该调用不妨将其传入以开始:

self.scrollPickerView = [[ScrollPickerView alloc] initWithFrame:CGRectZero];

或者,您可以保留当前的self.scrollPickerView = … 代码并将-initWithFrame: 更改为-init,如下所示:

- (id)init

    float screenWidth = [UIScreen mainScreen].bounds.size.width;
    float pickerWidth = screenWidth * 3 / 4;
    float xPoint = screenWidth / 2 - pickerWidth / 2;
    self = [super initWithFrame:CGRectMake(xPoint, 50.0f, pickerWidth, 180.0f)];

    if (self) 
        [self setToolbar];
        [self becomeFirstResponder];

        self.showsSelectionIndicator = YES;
        [self selectRow:3 inComponent:0 animated:YES];
    
    return self;

【讨论】:

以上是关于UIView 仅在第二次调用后显示的主要内容,如果未能解决你的问题,请参考以下文章

RestKit - 仅在第二次调用时将缓存保存到核心数据

SQL Reporting Services报告仅在第二次单击时加载

模态仅在第二次单击后显示

UIButton 切换标题。仅在第二次单击后更改

Android - Singleton Class仅在第二次刷新时更新

图像控制 ActualWidth 仅在第二次加载后才正确 - Image Cropper