我正在制作一款iOS游戏,它使用模态视图控制器让用户更改游戏设置。例如,如果使用一个组合示例,用户会在屏幕上选择5
作为cats
的数量,我只想让用户不超过4 bullets
。如果用户选择6 cats
,则他/她最多可以5 bullets
。他们永远不会有比猫更多的子弹。我正在使用UIPicker设置猫的数量和子弹的数量,因此Picker实际上允许用户设置3只猫和6发子弹。因此,当模态展开时,我希望能够停止展开并提供一条消息,告诉用户应该有更多的猫而不是子弹等。
问题:
1我知道如何比较在指定的展开方法(一个简单的任务)中选择的设置,但是如何停止模态展开,以便用户被迫重新调整设置以符合游戏规则。
2模式中是否有一种方法只显示用户选择猫数后的子弹数量,从而根据所选猫的数量限制可用的子弹数量?
更新。我可以在选择猫的数量之后调用pickerView:didSelectRow:inComponent,但我不知道如何使用它来限制子弹的数量。以下代码不起作用
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if(component == 0)
{
return [ _cats objectAtIndex:row];
[self pickerView:self didSelectRow:row inComponent:0];
}
else
{
return [_bullets objectAtIndex:row];
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (row == 3){
_bullets = @[@"1",@"2"]; //this part isn't working. not sure how to limit
//number of bullets based on row selected
}else if (row == 4){
_bullets = @[@"1", "2", "3"];
}
....
}
答案 0 :(得分:0)
根据评论,这里是一个示例视图控制器实现,用于在展开发生之前纠正错误的选择:
#import "CNBViewController.h"
@implementation CNBViewController {
UIPickerView * _picker;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
_picker = [UIPickerView new];
_picker.delegate = self;
_picker.dataSource = self;
[_picker setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:_picker];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_picker attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:20]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:_picker attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]];
}
return self;
}
#pragma mark - UIPickerViewDataSource methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
// Two components, cats and bullets
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if ( component == 0 ) {
// Let's have 10 rows for cats...
return 10;
}
else {
// ...and 6 rows for bullets.
return 6;
}
}
#pragma mark - UIPickerViewDelegate methods
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
// Just populate with numbers from 2 up for cats (component 0) and
// 1 up for bullets (component 1), otherwise we could end up with both
// being 1 which violates our constraint.
int offset;
if ( component == 0 ) {
offset = 2;
}
else {
offset = 1;
}
return [NSString stringWithFormat:@"%d", row + offset];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if ( component == 0 ) {
// Cats component changed, so get selected index of bullets component
NSInteger bullets = [pickerView selectedRowInComponent:1];
// If bullets is now greater than cats, reduce bullets
if ( bullets > row ) {
[pickerView selectRow:row inComponent:1 animated:YES];
}
}
else if ( component == 1 ) {
// Bullets component changed, so get selected index of cats component
NSInteger cats = [pickerView selectedRowInComponent:0];
// If bullets is now greater than cats, reduce bullets
if ( row > cats ) {
[pickerView selectRow:cats inComponent:1 animated:YES];
}
}
}
@end
注意:
视图控制器的头文件应该将该类声明为实现UIPickerViewDataSource
和UIPickerViewDelegate
协议。
为简单起见,没有放松,我刚刚展示了如何使选择器视图运行。
我将猫咪组件设置为只显示2个以上的值,子弹组件从1个向上开始。如果子弹必须始终小于猫,并且子弹从1开始,那么让猫开始低于2是没有意义的,因为它永远不会是有效的选择。因此,当每个组件中的选定行相同时,我们的条件(子弹必须显示不超过猫的数量小于1)才会满足,因为如果在两种情况下所选行都是3,那么猫将显示5,并且子弹将显示4.如果子弹组件的选定行大于猫组件的选定行,则不满足条件。
在pickerView:didSelectRow:inComponent:
中,如果猫组件发生了变化,我们只需查看项目符号组件中所选索引的值,如果它超过了猫的组件,我们就会设置它与猫的相等,以恢复我们的约束。
如果它是更改的子弹组件,我们会查看cat组件中所选索引的值,如果它超过了猫的值,我们再次设置它等于猫的值,有效地撤消我们刚收到通知的变更。
尝试使用它,更改任一组件以使右组件的值大于或等于左侧,当您松开触摸时,您将看到它变为可接受的值。