UI 보기에 터치 이벤트를 추가하는 방법은 무엇입니까?
UIView에 터치 이벤트를 추가하려면 어떻게 해야 합니까?
UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, nextY)] autorelease];
[headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown];
// ERROR MESSAGE: UIView may not respond to '-addTarget:action:forControlEvents:'
하위 클래스를 만들고 덮어쓰지 않습니다.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
iOS 3.2 이상에서는 제스처 인식기를 사용할 수 있습니다.예를 들어 탭 이벤트를 처리하는 방법은 다음과 같습니다.
//The setup code (in viewDidLoad in your view controller)
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleFingerTap];
//The event handling method
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
CGPoint location = [recognizer locationInView:[recognizer.view superview]];
//Do stuff here...
}
여러 가지 제스처가 내장되어 있습니다. 및 iOS 이벤트에 대한 하십시오.UIGestureRecognizer
저는 또한 도움이 될 수 있는 샘플 코드를 github에 많이 가지고 있습니다.
제스처 인식기
보기에 제스처 인식기를 추가할 때 알림을 받을 수 있는 일반적으로 사용되는 여러 가지 터치 이벤트(또는 제스처)가 있습니다.기본적으로 지원되는 제스처 유형은 다음과 같습니다.
UITapGestureRecognizer
(화면을 한 번 이상 짧게 누름)UILongPressGestureRecognizer
긴 터치(화면을 장시간 터치)UIPanGestureRecognizer
상하좌우 이동(화면 전체에서 손가락 이동)UISwipeGestureRecognizer
스와이프(손가락을 빠르게 이동)UIPinchGestureRecognizer
핀치(두 손가락을 함께 또는 분리하여 이동 - 일반적으로 확대/축소)UIRotationGestureRecognizer
회전(두 손가락을 원형 방향으로 이동)
이 외에도 사용자 지정 제스처 인식기를 직접 만들 수도 있습니다.
인터페이스 작성기에서 제스처 추가
개체 라이브러리에서 보기로 제스처 인식기를 끕니다.
아웃렛과 액션을 만들기 위해 문서 개요의 제스처에서 보기 컨트롤러 코드로 드래그합니다.
기본적으로 설정해야 하지만 보기에 대해 사용자 작업 사용이 true로 설정되어 있는지 확인합니다.
프로그래밍 방식으로 제스처 추가
프로그래밍 방식으로 제스처를 추가하려면 (1) 제스처 인식기를 만들고, (2) 이를 보기에 추가하고, (3) 제스처가 인식될 때 호출되는 메서드를 만듭니다.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var myView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// 1. create a gesture recognizer (tap gesture)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
// 2. add the gesture recognizer to a view
myView.addGestureRecognizer(tapGesture)
}
// 3. this method is called when a tap is recognized
@objc func handleTap(sender: UITapGestureRecognizer) {
print("tap")
}
}
메모들
- 그
sender
매개 변수는 선택 사항입니다.제스처에 대한 참조가 필요하지 않으면 생략할 수 있습니다.하지만 그렇게 할 경우에는 다음을 제거합니다.(sender:)
작업 메서드 이름 뒤에 있습니다. -
handleTap
메서드가 임의입니다.를 사용하여 원하는 이름을 .action: #selector(someMethodName(sender:))
.
기타 예제
이러한 보기에 추가한 제스처 인식기를 검토하여 작동 방식을 확인할 수 있습니다.
다음은 해당 프로젝트의 코드입니다.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tapView: UIView!
@IBOutlet weak var doubleTapView: UIView!
@IBOutlet weak var longPressView: UIView!
@IBOutlet weak var panView: UIView!
@IBOutlet weak var swipeView: UIView!
@IBOutlet weak var pinchView: UIView!
@IBOutlet weak var rotateView: UIView!
@IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Tap
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
tapView.addGestureRecognizer(tapGesture)
// Double Tap
let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap))
doubleTapGesture.numberOfTapsRequired = 2
doubleTapView.addGestureRecognizer(doubleTapGesture)
// Long Press
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(gesture:)))
longPressView.addGestureRecognizer(longPressGesture)
// Pan
let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(gesture:)))
panView.addGestureRecognizer(panGesture)
// Swipe (right and left)
let swipeRightGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(gesture:)))
let swipeLeftGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(gesture:)))
swipeRightGesture.direction = UISwipeGestureRecognizerDirection.right
swipeLeftGesture.direction = UISwipeGestureRecognizerDirection.left
swipeView.addGestureRecognizer(swipeRightGesture)
swipeView.addGestureRecognizer(swipeLeftGesture)
// Pinch
let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(gesture:)))
pinchView.addGestureRecognizer(pinchGesture)
// Rotate
let rotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(handleRotate(gesture:)))
rotateView.addGestureRecognizer(rotateGesture)
}
// Tap action
@objc func handleTap() {
label.text = "Tap recognized"
// example task: change background color
if tapView.backgroundColor == UIColor.blue {
tapView.backgroundColor = UIColor.red
} else {
tapView.backgroundColor = UIColor.blue
}
}
// Double tap action
@objc func handleDoubleTap() {
label.text = "Double tap recognized"
// example task: change background color
if doubleTapView.backgroundColor == UIColor.yellow {
doubleTapView.backgroundColor = UIColor.green
} else {
doubleTapView.backgroundColor = UIColor.yellow
}
}
// Long press action
@objc func handleLongPress(gesture: UILongPressGestureRecognizer) {
label.text = "Long press recognized"
// example task: show an alert
if gesture.state == UIGestureRecognizerState.began {
let alert = UIAlertController(title: "Long Press", message: "Can I help you?", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
// Pan action
@objc func handlePan(gesture: UIPanGestureRecognizer) {
label.text = "Pan recognized"
// example task: drag view
let location = gesture.location(in: view) // root view
panView.center = location
}
// Swipe action
@objc func handleSwipe(gesture: UISwipeGestureRecognizer) {
label.text = "Swipe recognized"
// example task: animate view off screen
let originalLocation = swipeView.center
if gesture.direction == UISwipeGestureRecognizerDirection.right {
UIView.animate(withDuration: 0.5, animations: {
self.swipeView.center.x += self.view.bounds.width
}, completion: { (value: Bool) in
self.swipeView.center = originalLocation
})
} else if gesture.direction == UISwipeGestureRecognizerDirection.left {
UIView.animate(withDuration: 0.5, animations: {
self.swipeView.center.x -= self.view.bounds.width
}, completion: { (value: Bool) in
self.swipeView.center = originalLocation
})
}
}
// Pinch action
@objc func handlePinch(gesture: UIPinchGestureRecognizer) {
label.text = "Pinch recognized"
if gesture.state == UIGestureRecognizerState.changed {
let transform = CGAffineTransform(scaleX: gesture.scale, y: gesture.scale)
pinchView.transform = transform
}
}
// Rotate action
@objc func handleRotate(gesture: UIRotationGestureRecognizer) {
label.text = "Rotate recognized"
if gesture.state == UIGestureRecognizerState.changed {
let transform = CGAffineTransform(rotationAngle: gesture.rotation)
rotateView.transform = transform
}
}
}
메모들
- 단일 보기에 여러 제스처 인식기를 추가할 수 있습니다.하지만 단순함을 위해 (스와이프 제스처를 제외하고) 그렇게 하지 않았습니다.프로젝트에 필요한 경우 제스처 인식기 설명서를 읽어야 합니다.그것은 꽤 이해할 수 있고 도움이 됩니다.
- 위의 예에서 알려진 문제: (1) Pan view는 다음 제스처 이벤트 시 프레임을 재설정합니다. (2) 스와이프 뷰는 첫 번째 스와이프 시 잘못된 방향에서 옵니다.(그러나 이 예제의 버그는 제스처 인식기의 작동 방식에 대한 사용자의 이해에 영향을 미치지 않습니다.
제 생각에 당신은 간단하게
UIControl *headerView = ...
[headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown];
즉, headerView는 UIControl에서 확장됩니다.
스위프트 3 & 스위프트 4
import UIKit
extension UIView {
func addTapGesture(tapNumber: Int, target: Any, action: Selector) {
let tap = UITapGestureRecognizer(target: target, action: action)
tap.numberOfTapsRequired = tapNumber
addGestureRecognizer(tap)
isUserInteractionEnabled = true
}
}
사용하다
yourView.addTapGesture(tapNumber: 1, target: self, action: #selector(yourMethod))
승인된 답변에 따라 매크로를 정의할 수 있습니다.
#define handle_tap(view, delegate, selector) do {\
view.userInteractionEnabled = YES;\
[view addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget:delegate action:selector]];\
} while(0)
ARC를 이매를는로ARC므로다없이 .release
콜.콜.
매크로 사용 예:
handle_tap(userpic, self, @selector(onTapUserpic:));
Swift 4.2 및 Xcode 10에서
의 UITapGestureRecognizer를 사용하여 터치 이벤트 추가
//Add tap gesture to your view
let tap = UITapGestureRecognizer(target: self, action: #selector(handleGesture))
yourView.addGestureRecognizer(tap)
// GestureRecognizer
@objc func handleGesture(gesture: UITapGestureRecognizer) -> Void {
//Write your code here
}
공유 클래스를 사용하려는 경우
//This is my shared class
import UIKit
class SharedClass: NSObject {
static let sharedInstance = SharedClass()
//Tap gesture function
func addTapGesture(view: UIView, target: Any, action: Selector) {
let tap = UITapGestureRecognizer(target: target, action: action)
view.addGestureRecognizer(tap)
}
}
View 컨트롤러에 view1, view2 및 view3라는 3개의 보기가 있습니다.
override func viewDidLoad() {
super.viewDidLoad()
//Add gestures to your views
SharedClass.sharedInstance.addTapGesture(view: view1, target: self, action: #selector(handleGesture))
SharedClass.sharedInstance.addTapGesture(view: view2, target: self, action: #selector(handleGesture))
SharedClass.sharedInstance.addTapGesture(view: view3, target: self, action: #selector(handleGesture2))
}
// GestureRecognizer
@objc func handleGesture(gesture: UITapGestureRecognizer) -> Void {
print("printed 1&2...")
}
// GestureRecognizer
@objc func handleGesture2(gesture: UITapGestureRecognizer) -> Void {
print("printed3...")
}
코드에 제스처 인식기를 추가하여 이 작업을 수행할 수 있습니다.
1단계: ViewController.m:
// Declare the Gesture.
UITapGestureRecognizer *gesRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:@selector(handleTap:)];
gesRecognizer.delegate = self;
// Add Gesture to your view.
[yourView addGestureRecognizer:gesRecognizer];
2단계: ViewController.m:
// Declare the Gesture Recogniser handler method.
- (void)handleTap:(UITapGestureRecognizer *)gestureRecognizer{
NSLog(@"Tapped");
}
참고: 여기 내 경우에 당신의 견해가 있었습니다.@property (strong, nonatomic) IBOutlet UIView *localView;
편집: *localView는 아래의 Main.storyboard에 있는 흰색 상자입니다.
Swift 버전은 다음과 같습니다.
// MARK: Gesture Extensions
extension UIView {
func addTapGesture(#tapNumber: Int, target: AnyObject, action: Selector) {
let tap = UITapGestureRecognizer (target: target, action: action)
tap.numberOfTapsRequired = tapNumber
addGestureRecognizer(tap)
userInteractionEnabled = true
}
func addTapGesture(#tapNumber: Int, action: ((UITapGestureRecognizer)->())?) {
let tap = BlockTap (tapCount: tapNumber, fingerCount: 1, action: action)
addGestureRecognizer(tap)
userInteractionEnabled = true
}
}
스위프트 3:
let tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGestureRecognizer(_:)))
view.addGestureRecognizer(tapGestureRecognizer)
func handleTapGestureRecognizer(_ gestureRecognizer: UITapGestureRecognizer) {
}
목표-C:
UIControl *headerView = [[UIControl alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, nextY)];
[headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown];
스위프트:
let headerView = UIControl(frame: CGRect(x: 0, y: 0, width: tableView.bounds.size.width, height: nextY))
headerView.addTarget(self, action: #selector(myEvent(_:)), for: .touchDown)
질문은 다음과 같습니다.
UIView에 터치 이벤트를 추가하려면 어떻게 해야 합니까?
탭 이벤트를 요청하는 것이 아닙니다.
특히 OP가 구현하고자 하는 것은UIControlEventTouchDown
전환UIView
UIControl
여기서 정답이 맞는 이유는Gesture Recognisers
에 대해 .touchDown
,.touchUpInside
,.touchUpOutside
또한 UIControl은 UIView에서 상속되므로 기능이 손실되지 않습니다.
원하는 것이 제스처 인식기만 있으면 사용할 수 있습니다.하지만 이 질문이 요구하는 것처럼 더 세밀한 제어를 원한다면 UIC 제어가 필요합니다.
https://developer.apple.com/documentation/uikit/uicontrol?language=objc https://developer.apple.com/documentation/uikit/uigesturerecognizer?language=objc
스위프트 5.3
폐쇄형 솔루션, 기반: 폐쇄형 UIGesture Recognizer
final class BindableGestureRecognizer: UITapGestureRecognizer {
private var action: () -> Void
init(action: @escaping () -> Void) {
self.action = action
super.init(target: nil, action: nil)
self.addTarget(self, action: #selector(execute))
}
@objc private func execute() {
action()
}
}
public extension UIView {
/// A discrete gesture recognizer that interprets single or multiple taps.
/// - Parameters:
/// - tapNumber: The number of taps necessary for gesture recognition.
/// - closure: A selector that identifies the method implemented by the target to handle the gesture recognized by the receiver. The action selector must conform to the signature described in the class overview. NULL is not a valid value.
func addTapGesture(tapNumber: Int = 1, _ closure: (() -> Void)?) {
guard let closure = closure else { return }
let tap = BindableGestureRecognizer(action: closure)
tap.numberOfTapsRequired = tapNumber
addGestureRecognizer(tap)
isUserInteractionEnabled = true
}
}
사용:
view.addTapGesture { [weak self] in
self?.view.backgroundColor = .red
}
간단하고 유용한 확장 기능:
extension UIView {
private struct OnClickHolder {
static var _closure:()->() = {}
}
private var onClickClosure: () -> () {
get { return OnClickHolder._closure }
set { OnClickHolder._closure = newValue }
}
func onTap(closure: @escaping ()->()) {
self.onClickClosure = closure
isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(onClickAction))
addGestureRecognizer(tap)
}
@objc private func onClickAction() {
onClickClosure()
}
}
용도:
override func viewDidLoad() {
super.viewDidLoad()
let view = UIView(frame: .init(x: 0, y: 0, width: 80, height: 50))
view.backgroundColor = .red
view.onTap {
print("View Tapped")
}
}
다음은 iOS 탭 제스처입니다. 먼저 아래와 같이 동작 아래에 아래 코드를 작성한 후에 제스처 인식기에 대한 동작을 만들어야 합니다.
- (IBAction)tapgesture:(id)sender
{
[_password resignFirstResponder];
[_username resignFirstResponder];
NSLog(@" TapGestureRecognizer tapped");
}
다른 방법은 보기에 투명 단추를 추가하는 것입니다.
UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom];
b.frame = CGRectMake(0, 0, headerView.width, headerView.height);
[headerView addSubview:b];
[b addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchDown];
그런 다음 클릭을 처리합니다.
- (void)buttonClicked:(id)sender
{}
클래스를 만들어 합니다.touchesBegan
그런 다음 보기에 추가할 수 있습니다.
이렇게 하면 하위 분류(요청) 대신 구성을 사용할 수 있습니다.
여러분도 SSEvent Listener를 사용해 보는 건 어떨까요?
제스처 인식기를 만들고 논리를 다른 방법으로 분리할 필요가 없습니다. SSEventListener
에서는 보기에 수신기 블록을 설정하여 원하는 경우 한 번 탭 제스처, 두 번 탭 제스처 및 N-탭 제스처, 길게 누르는 제스처를 청취할 수 있습니다.단일 탭 제스처 수신기를 설정하면 다음과 같이 됩니다.
[view ss_addTapViewEventListener:^(UITapGestureRecognizer *recognizer) { ... } numberOfTapsRequired:1];
언급URL : https://stackoverflow.com/questions/4660371/how-to-add-a-touch-event-to-a-uiview
'programing' 카테고리의 다른 글
도커 엔진과 도커 컨테이너가 작동하는지 확인하는 방법은 무엇입니까? (0) | 2023.05.24 |
---|---|
DateTime에서 AM/PM 값을 가져오려면 어떻게 해야 합니까? (0) | 2023.05.24 |
이클립스에서 코드를 자동으로 포맷하는 방법은? (0) | 2023.05.19 |
"아니..."아무것도 아니야" 대 "...아무 것도 아닙니다. (0) | 2023.05.19 |
jQuery를 사용하여 요소 유형 찾기 (0) | 2023.05.19 |