Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 是否有类似scrollviewDidScroll的uipickerview委托方法?_Iphone_Uipickerview_Delegatecommand - Fatal编程技术网

Iphone 是否有类似scrollviewDidScroll的uipickerview委托方法?

Iphone 是否有类似scrollviewDidScroll的uipickerview委托方法?,iphone,uipickerview,delegatecommand,Iphone,Uipickerview,Delegatecommand,我有一个定制的UIPickerview,我不想使用日期选择器。我想实现一个功能,当用户向下/向上滚动小时时,AM/PM组件在滚动小时时切换。这意味着我需要在调用pickerView didSelectRow之前切换它。有办法做到这一点吗 谢谢使用以下方法 - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { // put y

我有一个定制的UIPickerview,我不想使用日期选择器。我想实现一个功能,当用户向下/向上滚动小时时,AM/PM组件在滚动小时时切换。这意味着我需要在调用pickerView didSelectRow之前切换它。有办法做到这一点吗

谢谢

使用以下方法

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
     // put your logic here.
}
上面的方法来自UIPickerViewDeleteGate,如果用户使用pickerview选择任何元素,此方法将自动触发

希望对你有帮助

编辑

我认为您应该使用以下方法来检测-用户在哪个方向滚动

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    NSLog(@"scrolling to row is %@",[NSString stringWithFormat:@"index_%i",row]);
    return [NSString stringWithFormat:@"index_%i",row];
}
每当用户向上/向下滚动时,就会自动触发上述方法,类似于
UITableView
。请记住,
UIPickerView
使用的是私有的
UIPickerTableView
,因此我们无法检测到您想要的滚动方式

让我解释一下在pickerview中检测方向的方法

例如。可见行是
索引4、索引5、索引6、索引7
。现在,如果用户向下滚动
索引,将调用8
。类似地,如果用户正在向上滚动
索引,则将调用3


我希望这个把戏能解决你的问题。即使让我知道您对此的反馈。

也必须对事件使用以下两种UIPickerView委托方法:

是否结束滚动:

- (void)pickerView:(UIPickerView *)pV didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
    NSLog(@"pickerView didSelectRow %zd",row);
    // DID END SCROLL: CALL YOUR HEANDLER METHOD!!
}
将开始滚动:

- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
    // WILL START SCROLLING: CALL YOUR HEANDLER METHOD!!
    UILabel* label = (UILabel*)view;
    if (!label){
        label = [UILabel new];
        [label setFrame:frame];
        [label setBackgroundColor:[UIColor clearColor]];
        [label setFont:[UIFont fontWithName:FONT_QUICKSAND_BOLD size:12]];
        [label setTextAlignment:NSTextAlignmentRight];
        [label setLineBreakMode:NSLineBreakByTruncatingMiddle];
        [label setTextColor:UIColorFromRGB(0X2692ff)];
        }
    //Update labeltext here
    [label setText:[NSString stringWithFormat:@"row %zd",row]];
    return label;
}

显然,除了UIPickerview的建筑(第一次!);因此,当您完成构建piker时,您必须实现一个假DiEndScroll事件,或者ignore first将启动可见piker行的滚动

有一个技巧可以检测到这一点,但是没有委托方法/属性来检测其滚动与否

  • 把一项财产当作是廉价品
  • func-pickerView(\pickerView:UIPickerView,titleForRow行:Int,forComponent-component:Int)->String?
    或等效方法中,将IsCrolling设置为true
  • func-pickerView(pickerView:UIPickerView,didSelectRow-row-Int,incomonent-component-Int)中将isScrolling设置为false

  • 希望这能有所帮助,顺便说一句,上述所有答案都解释了这一点。不幸的是,上述解决方案(在调用titleForRow等数据源方法时设置标志,在调用didSelectRow时重置标志)很粗略,在许多情况下都不起作用。在许多情况下,如果用户没有滚动,则可以调用数据源方法,例如UI更改导致视图布局更改,也可以在didSelectRow之后立即调用数据源方法。您无法控制何时调用这些方法

    对于这个特定的问题,这些解决方案可能有效,因为滚动时总是调用这些方法,而不仅仅是滚动时。但是,在这些情况下,需要注意不要假设用户必须滚动。此外,如果您使用此标志管理状态机(如在滚动时禁用某些按钮并在滚动后启用),您将遇到麻烦

    最后,这只允许检测一个滚动条(有上面的警告),但它不会告诉您速度或当前值-因此很难判断何时切换AM/PM标签


    我能够可靠地检测滚动的唯一方法是通过在进行UI更改时设置的一堆标志和其他难看的黑客行为(比如在didSelectRow之后等待100毫秒,然后再次尝试检测滚动,因为我注意到在didSelectRow之后立即调用数据源)。向委托添加willScroll/didScroll方法似乎是Apple忽略添加的一件明显的事情。

    我刚刚找到了一种实现“pickerDidScroll”的方法,效果很好。关键点是将KVO添加到行视图中。这是我的密码:

    //picker view delegate
    
    - (UIView*)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
    
        if (!view) {
            view = [[RatchetScrollUnit alloc] initWithFrame:CGRectZero];
            //
            [((RatchetScrollUnit*)view) addRatchetObserver:self];
        }
        return view;
    }
    
    //KVO
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    
        if (self.ratchet) {
            NSInteger row = [self.ratchet selectedRowInComponent:0];
    
            if (row != _lastRow) {
                _lastRow = row;
    
                if (self.delegate && [self.delegate respondsToSelector:@selector(ratchetScrollerDidRatchetedToTooth:)]) {
    
                    [self.delegate ratchetScrollerDidRatchetedToTooth:row];
                }
            }
        }
    }
    

    试试看

    我已经知道这种方法了。问题是它在选择器停止滚动时触发,我需要在它仍在滚动时进行回调。谢谢!我不知道titleForRow在滚动时被调用。当我使用
    viewForRow
    时-
    titleForRow
    没有被调用,所以我使用
    viewForRow
    来检测滚动。作品将数字(3)中的“将isScrolling设置为true”修正为“将isScrolling设置为false”。
    @interface RatchetScrollUnit ()
    @property (nonatomic,assign) BOOL observed;
    @property (nonatomic,weak) NSObject *myObserver;
    @end
    
    @implementation RatchetScrollUnit
    
    - (instancetype)initWithFrame:(CGRect)frame {
        self = [super initWithFrame:frame];
    
        if (self) {
            _observed = NO;
            self.backgroundColor = [UIColor clearColor];
        }
        return self;
    }
    
    - (void)dealloc {
        if (self.observed) {
            [self removeObserver:self.myObserver forKeyPath:@"frame" context:nil];
        }
    }
    
    - (void)addRatchetObserver:(NSObject*)observer {
        if (self.observed) {
            return;
        }
        self.observed = YES;
        self.myObserver = observer;
        //
        [self addObserver:observer
               forKeyPath:@"frame"
                  options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew
                  context:nil];
    }