2010-05-18 29 views
24

Có cách nào để đặt trạng thái tùy chỉnh - không phải một trong các giá trị UIControlState hiện tại - cho một số UIControl không?Tôi có thể sử dụng các giá trị tùy chỉnh của UIControlState để kiểm soát của riêng tôi không?

Trong UIControlSate enum, có 16 bit có thể được sử dụng cho các quốc gia điều khiển tùy chỉnh:

UIControlStateApplication = 0x00FF0000,    // additional flags available for application use 

Vấn đề là state tài sản UIControl 's là readonly.

Tôi muốn đặt các hình nền khác nhau thành UIButton cho trạng thái tùy chỉnh của mình.

Trả lời

34

Bạn có thể sử dụng các trạng thái tùy chỉnh trong một lớp con của UIControl.

  • Tạo biến gọi là customState, trong đó bạn sẽ quản lý trạng thái tùy chỉnh của mình.
  • Nếu bạn cần đặt trạng thái, thực hiện hoạt động cờ của bạn với biến này và gọi [self stateWasUpdated].
  • Ghi đè state tài sản để trở [super state] Bitwise OR'd chống customState
  • Override của bạn enabled, selectedhighlighted setters để họ gọi [self stateWasUpdated]. Điều này sẽ cho phép bạn để đối phó với bất kỳ thay đổi trong trạng thái, không chỉ thay đổi để customState
  • Thực hiện stateWasUpdated với logic để đáp ứng với những thay đổi trong trạng thái

Trong tiêu đề:

#define kUIControlStateCustomState (1 << 16) 

@interface MyControl : UIControl { 
    UIControlState customState; 
} 

Trong việc thực hiện :

@implementation MyControl 

-(void)setCustomState { 
    customState |= kUIControlStateCustomState; 
    [self stateWasUpdated]; 
} 

-(void)unsetCustomState { 
    customState &= ~kUIControlStateCustomState; 
    [self stateWasUpdated]; 
} 

- (UIControlState)state { 
    return [super state] | customState; 
} 

- (void)setSelected:(BOOL)newSelected { 
    [super setSelected:newSelected]; 
    [self stateWasUpdated]; 
} 

- (void)setHighlighted:(BOOL)newHighlighted { 
    [super setHighlighted:newHighlighted]; 
    [self stateWasUpdated]; 
} 

- (void)setEnabled:(BOOL)newEnabled { 
    [super setEnabled:newEnabled]; 
    [self stateWasUpdated]; 
} 

- (void)stateWasUpdated { 
    // Add your custom code here to respond to the change in state 
} 

@end 
+4

Các UIControlState enum xác định rằng các quốc gia kiểm soát ứng dụng sử dụng mặt nạ 0x00FF0000. Điều đó có nghĩa là 1 << 16 đến 1 << 23. Bạn sử dụng 1 << 3 có hợp lệ không? Có thể nó có thể xung đột với các trạng thái kiểm soát trong tương lai mà táo có thể thêm vào không? –

+2

Cũng cần lưu ý; Nếu bạn định sử dụng các trạng thái tùy chỉnh để kiểm soát các tài nguyên tùy chỉnh trong UIButton chẳng hạn như tiêu đề, hình nền, hình ảnh, titleShadow hoặc attributedTitle. Bạn phải gọi setNeedsLayout sau khi thay đổi trạng thái tùy chỉnh của bạn. Nếu không, nút sẽ chỉ cập nhật hình dạng của nó sau khi nó được khai thác một lần nữa. –

+0

Chắc chắn không sử dụng 1 << 3, như Adam nói rằng sẽ xung đột trong các phiên bản tương lai của hệ điều hành. Sử dụng một số trong phạm vi mặt nạ bit 0x00FF0000. – christophercotton

5

Dựa trên @Nick answer Tôi đã triển khai một phiên bản đơn giản hơn. Phân lớp này hiển thị thuộc tính BOOL outlined tương tự chức năng với selected, highlightedenabled.

Làm những việc như [customButtton setImage:[UIImage imageNamed:@"MyOutlinedButton.png"] forState:UIControlStateOutlined] làm cho nó tự động hoạt động khi bạn cập nhật thuộc tính outlined.

Nhiều trong số này trạng thái + tài sản có thể được thêm nếu cần.


UICustomButton.h

extern const UIControlState UIControlStateOutlined; 

@interface UICustomButton : UIButton 
@property (nonatomic) BOOL outlined; 
@end 

UICustomButton.m

const UIControlState UIControlStateOutlined = (1 << 16); 

@interface OEButton() 
@property UIControlState customState; 
@end 

@implementation OEButton 

- (void)setOutlined:(BOOL)outlined 
{ 
    if (outlined) 
    { 
     self.customState |= UIControlStateOutlined; 
    } 
    else 
    { 
     self.customState &= ~UIControlStateOutlined; 
    } 
    [self stateWasUpdated]; 
} 

- (BOOL)outlined 
{ 
    return (self.customState & UIControlStateOutlined) == UIControlStateOutlined; 
} 

- (UIControlState)state { 
    return [super state] | self.customState; 
} 

- (void)stateWasUpdated 
{ 
    [self setNeedsLayout]; 
} 

// These are only needed if you have additional code on -(void)stateWasUpdated 
// - (void)setSelected:(BOOL)newSelected 
// { 
//  [super setSelected:newSelected]; 
//  [self stateWasUpdated]; 
// } 
// 
// - (void)setHighlighted:(BOOL)newHighlighted 
// { 
//  [super setHighlighted:newHighlighted]; 
//  [self stateWasUpdated]; 
// } 
// 
// - (void)setEnabled:(BOOL)newEnabled 
// { 
//  [super setEnabled:newEnabled]; 
//  [self stateWasUpdated]; 
// } 

@end 
1

Swift 3 phiên bản của câu trả lời của Nick:

extension UIControlState { 
    static let myState = UIControlState(rawValue: 1 << 16) 
} 

class CustomControl: UIControl { 

    private var _customState: UInt = 0 

    override var state: UIControlState { 
     return UIControlState(rawValue: super.state.rawValue | self._customState) 
    } 

    var isMyCustomState: Bool { 
     get { 
      return self._customState & UIControlState.myState.rawValue == UIControlState.myState.rawValue 
     } set { 
      if newValue == true { 
       self._customState |= UIControlState.myState.rawValue 
      } else { 
       self._customState &= ~UIControlState.myState.rawValue 
      } 
     } 
    } 
} 
Các vấn đề liên quan