2012-03-20 31 views
10

Tôi muốn chặn báo chí dài trên UITextview, nhưng không muốn tắt tùy chọn menu ngữ cảnh cùng một lúc.Làm thế nào để chặn báo chí dài trên UITextView mà không vô hiệu hóa menu ngữ cảnh?

Nếu tôi sử dụng trình nhận dạng cử chỉ trên chế độ xem văn bản, nó sẽ tắt trình đơn ngữ cảnh để tôi sử dụng phương pháp như dưới đây ngay bây giờ.

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {  
    //fire my method here 
} 

Nhưng, nó chỉ kích hoạt phương thức khi menu ngữ cảnh xuất hiện sau khi người dùng nhấn và giữ một số từ. Vì vậy, khi người dùng nhấn và giữ một khoảng trống, thì chỉ có kính lúp xuất hiện, tôi không thể kích hoạt phương thức đó vào lúc đó.

Có ai có ý tưởng hay hơn không? Cảm ơn!

////// Vấn đề Giải Quyết //////

Nhờ @danh và @Beppe, tôi đã làm cho nó thậm chí với vòi cử chỉ trên UITextView. Tôi muốn hiển thị thanh phông chữ trên chế độ xem văn bản bằng cách nhấn và giữ.

@Đầu tiên, tôi đã phân loại UITextview.

@interface LisgoTextView : UITextView { 
    BOOL  pressing_; 

} 

@property (nonatomic)   BOOL  pressing; 

@end 


@interface LisgoTextView (private) 
    - (void)longPress:(UIEvent *)event; 
@end 


@implementation LisgoTextView 

@synthesize pressing = pressing_; 


//--------------------------------------------------------------// 
#pragma mark -- Long Press Detection -- 
//--------------------------------------------------------------// 

- (void)longPress:(UIEvent *)event { 

    if (pressing_) { 

     //post notification to show font edit bar 
     NSNotification *fontEditBarNotification = [NSNotification notificationWithName:@"fontEditBarNotification" 
                       object:nil userInfo:nil]; 
     [[NSNotificationCenter defaultCenter] postNotification:fontEditBarNotification]; 
    }  
} 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesBegan:touches withEvent:event]; 
    [self performSelector:@selector(longPress:) withObject:event afterDelay:0.7]; 
    pressing_ = YES; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesEnded:touches withEvent:event];  
    pressing_ = NO; 
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesMoved:touches withEvent:event];  
    pressing_ = NO; 
} 

@Tôi đã sử dụng độ trễ để giải quyết xung đột với cử chỉ nhấn mà tôi đã triển khai trên UITextView.

- (void)tapGestureOnTextView:(UITapGestureRecognizer *)sender { 

    //cancel here if long press was fired first 
    if (cancelTapGesture_) { 
     return; 
    } 

    //don't fire show font bar 
    cancelShowFontBar_ = YES; 
    [self performSelector:@selector(enableShowFontBar) withObject:nil afterDelay:1.0]; 

    //method here 
} 


- (void)showFontEditBar { 

    //cancel here if tap gesture was fired first 
    if (cancelShowFontBar_) { 
     return; 
    } 

    if (fontEditBarExists_ == NO) { 

     //method here  

     //don't fire tap gesture 
     cancelTapGesture_ = YES; 
     [self performSelector:@selector(enableTapGesture) withObject:nil afterDelay:1.0]; 
    } 
} 

- (void)enableTapGesture { 
    cancelTapGesture_ = NO; 
} 

- (void)enableShowFontBar { 
    cancelShowFontBar_ = NO; 
} 

Trả lời

7

Tôi thường tránh subclassing trừ các tài liệu một cách rõ ràng cho thấy, điều này làm việc cho tôi. Nhấn và giữ menu ngữ cảnh. Rất tiếc - Câu trả lời chỉ được tải bởi @Beppe. Tâm trí tuyệt vời nghĩ như nhau :-)

@interface TextViewSubclass() 
@property(assign,nonatomic) BOOL pressing; 
@end 

@implementation TextViewSubclass 
@synthesize pressing=_pressing; 

- (void)longPress:(UIEvent *)event { 
    NSLog(@"long press"); 
} 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesBegan:touches withEvent:event]; 
    self.pressing = YES; 
    [self performSelector:@selector(longPress:) withObject:event afterDelay:2.0]; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesEnded:touches withEvent:event]; 
    [NSObject cancelPreviousPerformRequestsWithTarget:self]; 
    self.pressing = NO; 
} 
@end 
+0

ahahah: D Banzai cho "tâm trí tuyệt vời" !!! – Beppe

+0

Mặc dù tôi vẫn đang đấu tranh để giải quyết xung đột với tapGesture tôi đã thực hiện trên UITextview, đây là câu trả lời cho câu hỏi của tôi. Cảm ơn nhiều. –

+0

Tôi đã làm cho nó với cuộc xung đột để viết các lỗ hổng làm việc trên phần trả lời. –

0

bạn có thể sử dụng phương pháp textViewDidChangeSelection của giao thức UITextViewDelegate?

+0

Tôi tin rằng tôi cần chọn văn bản để chặn nội dung đó. :( –

+0

Ok, đó là một loại shot dài ... –

2

Đây là một chút khó khăn, nhưng nó hoạt động cho tôi.

tôi thêm một lớp con của UIButton trên đầu trang của UITextView của tôi, kiểm tra xem có chạm dài và vượt qua chúng để UITextView theo cách này:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    [super touchesBegan:touches withEvent:event]; 
    isLongTouchDetected = NO; 
    [self performSelector:@selector(longTouchDetected) withObject:nil afterDelay:1.0]; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    if (isLongTouchDetected == YES) { 
     [super touchesCancelled:touches withEvent:event]; 
    } else { 
     [super touchesEnded:touches withEvent:event]; 
     [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(longTouchDetected) object:nil]; 
    } 
} 

- (void)longTouchDetected { 
    isLongTouchDetected = YES; 
    // pass long touch to UITextView 
} 
+0

Tôi đã không thử cách này, vì tôi đã phân lớp UITextview.Nhưng, điều này cũng phải làm việc. Cảm ơn. –

+0

Bạn được chào đón !!! – Beppe

4

Điều này làm việc cho tôi. Tôi chỉ muốn kiểm soát những gì xảy ra khi người dùng nhấn hoặc nhấn và giữ liên kết

- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange 
{ 
    // check for long press event 
    BOOL isLongPress = YES; 
    for (UIGestureRecognizer *recognizer in self.commentTextView.gestureRecognizers) { 
     if ([recognizer isKindOfClass:[UILongPressGestureRecognizer class]]){ 
      if (recognizer.state == UIGestureRecognizerStateFailed) { 
       isLongPress = NO; 
      } 
     } 
    } 

    if (isLongPress) { 
     // user long pressed a link, do something 
    } else { 
     // user tapped on a link, do something 
    } 

    // return NO cause you dont want the normal behavior to occur 
    return NO; 
} 
+0

Giải pháp thông minh! – Johnny

+0

Điều này không thành công đối với tôi trong iOS 9. Khi NSLogging công nhận, có một trình nhận dạng bí ẩn mới trong trạng thái 'Không thành công '. Tôi chuyển logic xung quanh để tìm kiếm ít nhất một trình nhận dạng báo chí dài trong trạng thái 'Bắt ​​đầu'. Vẫn còn loại hackish, nhưng làm việc trong iOS 8 và 9 bây giờ. Xem bài đăng bên dưới bằng mã mới (đăng riêng để có thể định dạng mã). – chr

+0

Tôi nghĩ lý do tại sao điều này không hoạt động là 'UIPreviewGestureRecognizer' là lớp con của' UILongPressGestureRecognizer' và cái đó không thành công. Vì vậy, tôi nghĩ rằng thay vì 'isKindOfClass' chỉ cần sử dụng' isMemberOfClass' để không kiểm tra các lớp con. – josip04

3

Thích ứng với câu trả lời của Lucas Chwe để làm việc trên iOS 9 (và 8). Xem bình luận trong câu trả lời của mình.

Gợi ý: đảo ngược logic bằng cách bắt đầu bằng "không bấm lâu", sau đó chuyển sang "báo chí dài được phát hiện" nếu ít nhất một UILongPressGestureRecognizer ở trạng thái Began.

BOOL isLongPress = NO; 
for (UIGestureRecognizer *recognizer in textView.gestureRecognizers) { 
    if ([recognizer isKindOfClass:[UILongPressGestureRecognizer class]]) { 
     if (recognizer.state == UIGestureRecognizerStateBegan) { 
      isLongPress = YES; 
     } 
    } 
} 

Vẫn còn hơi khó hiểu nhưng làm việc cho iOS 8 và 9 bây giờ.

0

Đối với SWIFT [Way dễ nhất]

extension UITextField { 

    override public func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool { 
     if action == "paste:" { 
      return false 
     } 

     return super.canPerformAction(action, withSender: sender) 
    } 

    override public func addGestureRecognizer(gestureRecognizer: UIGestureRecognizer) { 
     if gestureRecognizer.isKindOfClass(UILongPressGestureRecognizer) { 
      gestureRecognizer.enabled = false 
     } 
     super.addGestureRecognizer(gestureRecognizer) 
     return 
    } 
} 

Trên mã có cũng có chức năng cho vô hiệu hóa "PASTE" tùy chọn trong menu nội dung.

Các vấn đề liên quan