动态创建的 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
的框架内。在编写代码时,虽然UIToolbar
是UIPickerView
的子视图,但工具栏在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;
不要忘记您的 pickerCancel 和 pickerDone 函数,当然还有 itemSortPicker 的委托方法.
希望能解决你的问题。
【讨论】:
以上是关于动态创建的 UIBarButtonItem 不会在点击时触发的主要内容,如果未能解决你的问题,请参考以下文章
添加到情节提要的 UIBarButtonItem 在运行时不会出现
如果在工具栏中点击,UIBarButtonItem 不会突出显示?