Câu hỏi Sự kiện thay đổi UISegmentedControl không kích hoạt trong iOS5


Tôi có một UISegmentedControl có sự kiện "Giá trị thay đổi" được kết nối trong bộ dựng giao diện để gọi bộ điều khiển của tôi -(IBAction)segmentChangeAction:(id)sender;

Khi người dùng chạm vào điều khiển để thay đổi phân đoạn đã chọn, như mong đợi segmentChangeAction được gọi là trong iOS4 hoặc iOS5.

Khi tôi lập trình thay đổi phân đoạn đã chọn thông qua segmentedControl.selectedSegmentIndex = newIndex;, trên iOS4 segmentChangeAction được gọi và phân đoạn phản ánh lựa chọn mới. Tuy nhiên trên iOS5 segmentChangeAction Là không phải được gọi, nhưng phân đoạn không phản ánh lựa chọn mới.

Đây có phải là sự thay đổi trong iOS5 không? Tôi có thể làm gì để có được segmentChangeAction được gọi trên iOS5 khi tôi thay đổi lựa chọn theo chương trình?


35
2017-11-08 17:38


gốc




Các câu trả lời:


Đây là thay đổi trong iOS 5 để UISegmentedControl nhất quán với tất cả các điều khiển khác.

Ý tưởng là hành động sẽ chỉ được kích hoạt tự động do kết quả của tương tác người dùng. Trước iOS 5, UISegmentedControlhành động của sẽ bị sa thải vì tương tác của người dùng  tương tác có lập trình. Tuy nhiên, bắt đầu thay đổi theo chương trình có nghĩa là bạn cũng có thể làm [myControl sendActionsForControlEvents:UIControlEventValueChanged] bản thân bạn.

Tuy nhiên, bạn phải cẩn thận với điều này. Nói bạn đồng ý:

[segmentedControl setSelectedSegmentIndex:newIndex];
[segmentedControl sendActionsForControlEvents:UIControlEventValueChanged];

Nếu bạn xây dựng và chạy trên iOS 5, nó hoạt động như bạn mong đợi. Nếu bạn xây dựng và chạy ứng dụng này trên iOS 4, bạn sẽ nhận được các hành động của mình được kích hoạt hai lần (một lần khi bạn setSelectedSegmentIndex và một lần nữa khi bạn sendActions...).

Cách này là để làm một số loại bảo vệ. Đây có thể là kiểm tra thời gian chạy để cho biết rằng bạn đang chạy trên thiết bị iOS 5+ hoặc thậm chí có thể là thứ gì đó bình thường hơn, như sau:

// changingIndex is a BOOL ivar
changingIndex = YES;
[segmentedControl setSelectedSegmentIndex:newIndex];
changingIndex = NO;
[segmentedControl sendActionsForControlEvents:UIControlEventValueChanged];

và sau đó trong phương pháp hành động của bạn ...

- (void)segmentedControlSelectedIndexChanged:(id)sender {
  if (!changingIndex) {
    // your action code here, guaranteed to only run as a result of the sendActions... msg
  }
}

69
2017-11-08 17:43



Cảm ơn bạn đã giải thích chi tiết! Tôi đã làm điều đơn giản nhất (gọi điện segmentChangeAction ngay sau khi thay đổi chỉ mục), đã xác minh rằng không có vấn đề với mã này được gọi hai lần trên iOS <5. Nhưng tôi cảm thấy hạnh phúc hơn nhiều khi biết tại sao tôi phải làm điều này, cảm ơn bạn. - Clafou
@Vin không phải năm nay; Tôi quá bận rộn để cho nó sự chú ý là một người điều hành xứng đáng. - Dave DeLong
@ Clafou bạn được chào đón! Và nếu bạn tìm thấy UIControl điều đó có không phải theo hành vi này, làm ơn tập tin lỗi và nó sẽ được sửa. :) - Dave DeLong
@Dave thật tệ ... trông giống như năm nay, chúng tôi sẽ không có ai từ iOS hoặc khách quan c :( - Vin
@Vin Brad Larson, BoltClock và Moshe đã được đề cử và tất cả đều hoạt động trong các thẻ có liên quan đến Cocoa. - Dave DeLong


Tôi tìm thấy một cách khác, có thể dễ hiểu hơn một chút bạn có thể mở rộng UISegmentedControl và thêm hành động đích vào phương thức init và gọi phương thức ủy nhiệm để kích hoạt thay đổi giá trị

đây là mã ví dụ

tệp tiêu đề trông như thế này

#import <UIKit/UIKit.h>
@class CGUISegmentedControl;

@protocol CGUISegmentedControlDelegate <NSObject>

@optional
- (void) segmentedControl:(CGUISegmentedControl *) control valueChangedTo:(NSInteger) nValue;

@end

@interface CGUISegmentedControl : UISegmentedControl

@property (nonatomic,unsafe_unretained) id <CGUISegmentedControlDelegate> delegate;

@end

.m tệp

    #import "CGUISegmentedControl.h"

@implementation CGUISegmentedControl

@synthesize delegate                = _delegateAction;

- (void) addTargetAction {

    [self addTarget:self action:@selector(indexChanged:) forControlEvents:UIControlEventValueChanged];

}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self addTargetAction];
    }
    return self;
}

- (id) initWithCoder:(NSCoder *)aDecoder {

    self = [super initWithCoder:aDecoder];
    if (self) {
        [self addTargetAction];
    }
    return self;

}

- (id) initWithItems:(NSArray *)items {

    self = [super initWithItems:items];
   if (self) {
        [self addTargetAction];
    }
    return self;
}

- (id) init {

    self = [super init];
    if (self) {
        [self addTargetAction];
    }
    return self;

}

- (void) indexChanged:(id) sender {

    if (_delegateAction && [_delegateAction respondsToSelector:@selector(segmentedControl:valueChangedTo:)])
        [_delegateAction segmentedControl:self valueChangedTo:self.selectedSegmentIndex];


}

@end

Và bạn có thể đặt đại biểu trong lớp gọi


5
2017-10-16 11:26