[英]iOS: Handling long press and drag to select another button. (Like the keyboard)
我很難找到如何處理觸摸事件的正確文檔,以支持鍵盤的類似行為。
我想要的是一個按鈕,當我長按它時,它會在按鈕上方顯示一個自定義視圖控制器,但我希望用戶能夠將手指拖動到其他按鈕之一(不要將手指從屏幕上移開) 。
我有一個長按按鈕,它的自定義視圖控制器都設置和工作。 我無法想象的是如何支持從第一個按鈕拖動到視圖控制器中的另一個按鈕以便能夠選擇它。
我嘗試過使用子類UIButton,我試過這個:
[self addTarget:self action:@selector(onDragOver:) forControlEvents:UIControlEventTouchDragEnter];
但這不起作用。
我也發現了這個問題如何長按后跟蹤按鈕選擇? 這正是我試圖復制的功能。 但是沒有答案。
這是我的解決方案。 訣竅是你必須使用hitTest:。
首先,您將手勢識別器添加到作為普通按鈕的按鈕 - 您要打開上下文菜單/自定義視圖控制器的按鈕。
然后在你的手勢識別器回調中,你使用hitTest:來確定用戶是否超過你的自定義按鈕並手動更新它的狀態。
- (id) init {
//add a long press gesture recognizer
UILongPressureGestureRecognizer * gesture = [[UILongPressureGestureRecognizer alloc] initWithTarget:self action:@selector(onLongTap:)];
[self.myButton addGestureRecognizer:gesture];
}
- (void) onLongTap:(UIGestureRecognizer *) gesture {
if(gesture.state == UIGestureRecognizerStateBegan) {
//display your view controller / context menu over the button
}
if(gesture.state == UIGestureRecognizerStateEnded) {
//gesture stopped, use hitTest to find if their finger was over a context button
CGPoint location = [gesture locationInView:self.view];
CGPoint superviewLocation = [self.view.superview convertPoint:location fromView:self.view];
UIView * view = [self.view.superview hitTest:superviewLocation withEvent:nil];
if([view isKindOfClass:[MMContextMenuButton class]]) {
//their finger was over my custom button, tell the button to send actions
MMContextMenuButton * button = (MMContextMenuButton *) view;
[self hideAndSendControlEvents:UIControlEventTouchUpInside];
if(self.draggedContextMenuButton == button) {
self.draggedContextMenuButton = nil;
}
}
if(self.draggedContextMenuButton) {
[self sendActionsForControlEvents:UIControlEventTouchUpInside];
}
self.draggedContextMenuButton = nil;
}
if(gesture.state == UIGestureRecognizerStateChanged) {
//gesture changed, use hitTest to see if their finger
//is over a button. Manually have to tell the button
//that it should update it's state.
CGPoint location = [gesture locationInView:self.view];
CGPoint superviewLocation = [self.view.superview convertPoint:location fromView:self.view];
UIView * view = [self.view.superview hitTest:superviewLocation withEvent:nil];
if([view isKindOfClass[MMContextMenuButton class]]) {
MMContextMenuButton * button = (MMContextMenuButton *) view;
if(self.draggedContextMenuButton != button) {
[self.draggedContextMenuButton dragOut];
}
self.draggedContextMenuButton = button;
[button dragOver];
}
}
}
//////////////
#import "MMContextMenuButton.h"
#import "MMContextMenus.h"
@implementation MMContextMenuButton
- (id) initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
self.layer.cornerRadius = 4;
self.adjustsImageWhenHighlighted = FALSE;
self.adjustsImageWhenDisabled = FALSE;
self.backgroundColor = [UIColor clearColor];
[self setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[self setTitleColor:[UIColor colorWithRed:0.435 green:0.745 blue:0.867 alpha:1] forState:UIControlStateNormal];
[self addTarget:self action:@selector(onHighlight:) forControlEvents:UIControlEventTouchDown];
[self addTarget:self action:@selector(onRelease:) forControlEvents:UIControlEventTouchUpOutside&UIControlEventTouchUpOutside];
return self;
}
- (void) onHighlight:(id) sender {
self.backgroundColor = [UIColor colorWithRed:0.435 green:0.745 blue:0.867 alpha:1];
}
- (void) onRelease:(id) sender {
self.backgroundColor = [UIColor clearColor];
}
- (void) hideAndSendControlEvents:(UIControlEvents) events {
[self dragOut];
[self sendActionsForControlEvents:events];
[[MMContextMenus instance] hideContextMenus];
}
- (void) dragOver {
self.highlighted = TRUE;
self.backgroundColor = [UIColor colorWithRed:0.435 green:0.745 blue:0.867 alpha:1];
}
- (void) dragOut {
self.highlighted = FALSE;
self.backgroundColor = [UIColor clearColor];
}
@end
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.