[iphone] iOS의 기본 드래그 앤 드롭
사용자가 드래그 앤 드롭 할 수있는 차량이 주변을 돌아 다니는 뷰를 갖고 싶습니다. 이를위한 최고의 대규모 전략은 무엇이라고 생각하십니까? 차량을 나타내는보기 또는 더 큰보기에서 터치 이벤트를 얻는 것이 가장 좋습니까? 드래그 앤 드롭에 사용한 간단한 패러다임이 만족 스럽습니까? 다른 전략의 단점은 무엇입니까?
답변
UIView
배경 이미지와 많은 씬 이 있다고 가정하면 vehicles
각각의 새 차량을 다음과 같이 정의 할 수 있습니다 UIButton
(UIImageView도 작동 할 것임).
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(imageTouch:withEvent:) forControlEvents:UIControlEventTouchDown];
[button addTarget:self action:@selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragInside];
[button setImage:[UIImage imageNamed:@"vehicle.png"] forState:UIControlStateNormal];
[self.view addSubview:button];
그런 다음 UIControlEventTouchDragInside
이벤트 에 응답하여 원하는 곳으로 차량을 이동할 수 있습니다 . 예 :
- (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event
{
CGPoint point = [[[event allTouches] anyObject] locationInView:self.view];
UIControl *control = sender;
control.center = point;
}
전체 장면을 관리하는 것과 비교하여 개별 차량이 자체 드래그를 처리하는 것이 훨씬 쉽습니다.
답변
ohho의 답변 외에도 유사한 구현을 시도했지만 “빠른”드래그 및 드래그 센터링 문제가 없습니다.
버튼 초기화는 …
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragInside];
[button addTarget:self action:@selector(imageMoved:withEvent:) forControlEvents:UIControlEventTouchDragOutside];
[button setImage:[UIImage imageNamed:@"vehicle.png"] forState:UIControlStateNormal];
[self.view addSubview:button];
및 방법 구현 :
- (IBAction) imageMoved:(id) sender withEvent:(UIEvent *) event
{
UIControl *control = sender;
UITouch *t = [[event allTouches] anyObject];
CGPoint pPrev = [t previousLocationInView:control];
CGPoint p = [t locationInView:control];
CGPoint center = control.center;
center.x += p.x - pPrev.x;
center.y += p.y - pPrev.y;
control.center = center;
}
나는 이것이 답을위한 완벽한 해결책이라고 말하지 않습니다. 그럼에도 불구하고 나는 이것이 드래그를위한 가장 쉬운 해결 책임을 발견했습니다.
답변
여러 다른 uiview간에 uiview를 드래그 / 드롭하려는 경우가있었습니다. 이 경우 모든 드롭 존과 모든 드래그 게이블 오브젝트가 포함 된 수퍼 뷰에서 팬 이벤트를 추적하는 최상의 솔루션을 찾았습니다. 실제 드래그 된 뷰에 이벤트 리스너를 추가하지 않은 주된 이유는 드래그 된 뷰에 대한 수퍼 뷰를 변경하자마자 진행중인 팬 이벤트를 잃었 기 때문입니다.
대신 단일 또는 다중 드롭 영역에서 사용할 수있는 다소 일반적인 드래그 드롭 솔루션을 구현했습니다.
여기에서 볼 수있는 간단한 예제를 만들었습니다. 다른 여러 uiview간에 드롭 uiviews를 드래그합니다.
다른 방향으로 가기로 결정했다면 uibutton 대신 uicontrol을 사용해보십시오. addTarget 메서드를 선언하고 확장하기가 훨씬 더 쉽습니다. 따라서 사용자 지정 상태와 동작을 제공합니다.
답변
저는 실제로 차량 뷰 에서 드래그를 추적 합니다. 특별한 이유가없는 한 큰보기보다는 자체에서 입니다.
사용자가 항목을 화면에 끌어 놓아 놓을 수있는 경우가 있습니다. 이 경우에는 상위 뷰 와 하위 뷰 를 모두 실험했습니다. 드래그 할 있는 . UIView에 몇 개의 “드래그 가능한”뷰를 추가하고 드래그 할 수있는 방법을 처리하면 코드가 더 깔끔하다는 것을 알았습니다. 부모 UIView에 대한 간단한 콜백을 사용하여 새 위치가 적합한 지 확인했습니다. 그래서 애니메이션으로 나타낼 수 있습니다.
갖는 상위 뷰 같아요 드래그 트랙 것은 좋은대로,하지만이 아닌 드래그 뷰를 추가 할 경우 그게 약간 더 혼란을 만드는 여전히 상호 작용 버튼 등 사용자와.
답변
-(void)funcAddGesture
{
// DRAG BUTTON
UIPanGestureRecognizer *panGestureRecognizer;
panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(dragButton:)];
panGestureRecognizer.cancelsTouchesInView = YES;
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(50, 100, 60, 60);
[button addTarget:self action:@selector(buttontapEvent) forControlEvents:UIControlEventPrimaryActionTriggered];
[button setImage:[UIImage imageNamed:@"button_normal.png"] forState:UIControlStateNormal];
[button addGestureRecognizer:panGestureRecognizer];
[self.view addSubview:button];
}
- (void)dragButton:(UIPanGestureRecognizer *)recognizer {
UIButton *button = (UIButton *)recognizer.view;
CGPoint translation = [recognizer translationInView:button];
float xPosition = button.center.x;
float yPosition = button.center.y;
float buttonCenter = button.frame.size.height/2;
if (xPosition < buttonCenter)
xPosition = buttonCenter;
else if (xPosition > self.view.frame.size.width - buttonCenter)
xPosition = self.view.frame.size.width - buttonCenter;
if (yPosition < buttonCenter)
yPosition = buttonCenter;
else if (yPosition > self.view.frame.size.height - buttonCenter)
yPosition = self.view.frame.size.height - buttonCenter;
button.center = CGPointMake(xPosition + translation.x, yPosition + translation.y);
[recognizer setTranslation:CGPointZero inView:button];
}
- (void)buttontapEvent {
NSLog(@"buttontapEvent");
}
답변
오호의 답변이 잘 맞았습니다. 신속한 2.x 버전이 필요한 경우 :
override func viewDidLoad() {
let myButton = UIButton(type: .Custom)
myButton.setImage(UIImage(named: "vehicle"), forState: .Normal)
// drag support
myButton.addTarget(self, action:#selector(imageMoved(_:event:)), forControlEvents:.TouchDragInside)
myButton.addTarget(self, action:#selector(imageMoved(_:event:)), forControlEvents:.TouchDragOutside)
}
private func imageMoved(sender: AnyObject, event: UIEvent) {
guard let control = sender as? UIControl else { return }
guard let touches = event.allTouches() else { return }
guard let touch = touches.first else { return }
let prev = touch.previousLocationInView(control)
let p = touch.locationInView(control)
var center = control.center
center.x += p.x - prev.x
center.y += p.y - prev.y
control.center = center
}
답변
iOS 11에서 드래그 앤 드롭을 수행하는 가장 좋은 방법은 다음과 같습니다.