动态创建的 UIBarButtonItem 不会在点击时触发

Posted

技术标签:

【中文标题】动态创建的 UIBarButtonItem 不会在点击时触发【英文标题】:Dynamically created UIBarButtonItem doesn't trigger on tap 【发布时间】:2014-11-24 20:27:36 【问题描述】:

我有一个 UIPickerView,它在父视图的负载上附加了一个 UIToolbar,并使用以下代码:

- (void)viewDidLoad 
    [super viewDidLoad];

    self.itemSortPicker.hidden = false;

    pickerData = @[@"Name",@"Item Level",@"Crafting Level",@"Profit",@"Profit Percentage",@"Sell Price",@"Buy Price",@"Supply",@"Demand",@"Rarity"];

    self.itemSortPicker.dataSource = self;
    self.itemSortPicker.delegate = self;


    UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];

    pickerToolbar.barStyle = UIBarStyleDefault;
    [pickerToolbar sizeToFit];

    [pickerToolbar setFrame:CGRectMake(0, -pickerToolbar.bounds.size.height, 320, 44)];

    NSMutableArray *barItems = [[NSMutableArray alloc] init];


    UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(pickerCancel)];
    [barItems addObject:cancelBtn];

    UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
    [barItems addObject:flexSpace];

    UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(pickerDone)];
    [barItems addObject:doneBtn];

    [pickerToolbar setItems:barItems animated:YES];

    CGRect pickerRect = self.itemSortPicker.bounds;
    self.itemSortPicker.bounds = pickerRect;
    self.itemSortPicker.frame = CGRectMake(0, 44, 320, 216);

    [self.itemSortPicker addSubview:pickerToolbar];


现在的问题是,当我点击“完成”或“取消”按钮时,关联的方法不会触发。该方法不带任何参数,只执行 NSLog 操作。 PickerView 没有从栏中获得焦点,因为当我点击并拖动按钮时,PickerView 不会改变。

【问题讨论】:

再仔细检查一下...您的选择器视图已启用用户交互? 选择器本身可以交互。我可以把它拖来拖去。 接口是否在 .h 文件中? “UIPickerViewDataSource,UIPickerViewDelegate”?也不要忘记添加 [pickerView setDataSource: self]; [pickerView setDelegate: self]; 哦,我用self.itemSortPicker.dataSource = self;[pickerView setDataSource: self];一样吗? 哦,没关系,我看到了问题......我会发布一个答案。一秒…… 【参考方案1】:

问题在于UIToolbar 并不完全位于UIPickerView 的框架内。在编写代码时,虽然UIToolbarUIPickerView 的子视图,但工具栏在UIPickerView 上方是-pickerToolbar.bounds.size.height

[pickerToolbar setFrame:CGRectMake(0, -pickerToolbar.bounds.size.height, 320, 44)];

因此您无法与其按钮交互,因为它挂在其父视图框架的边缘。例如,如果您像这样更改了 pickerToolbar 框架:

[pickerToolbar setFrame:CGRectMake(0, 0, 320, 44)];

你应该能够与之交互。

如果您需要在UIPickerView 上方的特定位置-pickerToolbar.bounds.size.height,我建议不要将其作为子视图添加到UIPickerView,而是将其作为子视图适当地放置到UIPickerView 的超级视图中。一般来说,如果您需要与子视图交互,它需要完全在其父视图的框架内。

编辑:在这种情况下,如果您打算将工具栏添加到超级视图,如下所示:

[self.view addSubview:pickerToolbar];

我建议试试这个框架以保持你原来的位置:

[pickerToolbar setFrame:CGRectMake(self.itemSortPicker.frame.origin.x, self.itemSortPicker.frame.origin.y - pickerToolbar.bounds.size.height, 320, 44)];

(为了计算这个新框架,我将UIPicker 的 x 和 y 原点值添加到框架的 x 和 y 以适应视图坐标系的变化。)

【讨论】:

是的,如果我使用您所做的更正,则工具栏将放置在 UIPickerView 的顶部。从那以后,如果我尝试使用该栏,它只会与选择器交互 @JamEngulfer221 可能是这样,所以我删除了那个例子(不是更正,而是例子)。我的观点是,当工具栏在其父视图之外时(即 -pickerToolbar.bounds.size.height),您无法与工具栏进行交互,因此最好的解决方案是执行我在上一段中描述的操作,而不是放置工具栏如果您不能将它包含在选择器的框架中,则在选择器中。 我将工具栏添加到我认为是父视图的位置:[self.view addSubview:pickerToolbar];,但现在工具栏本身不见了。 @JamEngulfer221 如果您将框架保持为CGRectMake(0, -pickerToolbar.bounds.size.height, 320, 44),那么会发生这种情况,因为您的工具栏再次位于视图上方的-pickerToolbar.bounds.size.height。您需要调整框架,使其在框架内。 @JamEngulfer221 哦,明白了...然后我将在我之前使用 CGRect(0,0,...) 的示例中添加回以供将来寻求答案的人使用。很高兴听到它有效!【参考方案2】:

我不确定问题是因为按钮或工具栏本身还是因为pickerview,但更好的方法是通过编程完成所有操作,并且您必须从视图中删除pickerview:

- (void)viewDidLoad 
    [super viewDidLoad];

    pickerData = @[@"Name",@"Item Level",@"Crafting Level",@"Profit",@"Profit Percentage",@"Sell Price",@"Buy Price",@"Supply",@"Demand",@"Rarity"];

    UIPickerView *itemSortPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, 320, 162)];
    itemSortPicker.dataSource = self;
    itemSortPicker.delegate = self;
    itemSortPicker.showsSelectionIndicator = YES;

    UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(pickerCancel)];
    UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
    UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(pickerDone)];

    UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
    [pickerToolbar setBarStyle:UIBarStyleDefault];
    [pickerToolbar sizeToFit];
    [toolBar setItems:@[cancelBtn,flexSpace,doneBtn]];

    BlaBlaTextField.delegate = self;
    BlaBlaTextField.inputView = itemSortPicker;
    BlaBlaTextField.inputAccessoryView = pickerToolbar;

不要忘记您的 pickerCancelpickerDone 函数,当然还有 itemSortPicker 的委托方法.

希望能解决你的问题。

【讨论】:

以上是关于动态创建的 UIBarButtonItem 不会在点击时触发的主要内容,如果未能解决你的问题,请参考以下文章

添加到情节提要的 UIBarButtonItem 在运行时不会出现

如果在工具栏中点击,UIBarButtonItem 不会突出显示?

UIBarButtonItem 在视图更改之前不会被禁用

UIBarButtonItem 带有图像和文本以及边框?

UIBarButtonItem 在 iOS 7 的 UIToolbar 上不显示

如何在代码中更改 UIBarButtonItem 的样式