programing

Swift에서 선택기에 인수 전달

topblog 2023. 8. 6. 09:05
반응형

Swift에서 선택기에 인수 전달

내 보기 중 하나에 UITapGesture Recognizer를 프로그래밍 방식으로 추가하고 있습니다.

let gesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(modelObj:myModelObj)))

self.imageView.addGestureRecognizer(gesture)

func handleTap(modelObj: Model) {
  // Doing stuff with model object here
}

첫 번째 문제는 "'#selector' 인수가 '@Objc' 메서드, 속성 또는 이니셜라이저를 참조하지 않는다는 것입니다.

멋집니다. 그래서 @objc를 handleTap 시그니처에 추가했습니다.

@objc func handleTap(modelObj: Model) {
  // Doing stuff with model object here
}

이제 "Method can't marked @objc"라는 오류가 발생합니다. 왜냐하면 매개 변수의 유형을 Objective-C로 표시할 수 없기 때문입니다.

건물 지도의 이미지일 뿐이며, 관심 지점의 위치를 나타내는 핀 이미지도 있습니다.사용자가 이 핀 중 하나를 탭할 때 어떤 관심 지점을 탭했는지 알고 싶습니다. 그리고 이러한 관심 지점을 설명하는 모델 개체가 있습니다.저는 이 모델 객체를 사용하여 핀 이미지에 지도상의 좌표를 제공하기 때문에 제스처 핸들러에게 객체를 보내는 것이 쉬울 것이라고 생각했습니다.

당신이 몇 가지 오해를 하고 있는 것 같습니다.

대상/액션을 사용할 때 기능 서명은 특정 형식이어야 합니다.

func doSomething()

또는

func doSomething(sender: Any)

또는

func doSomething(sender: Any, forEvent event: UIEvent)

어디서…

sender매개 변수는 작업 메시지를 보내는 제어 개체입니다.

의 경우,은 당의경우, 사은람보입니다.UITapGestureRecognizer

또한.#selector()에는 func 서명이 포함되어야 하며 전달된 매개 변수는 포함되지 않습니다.에 대해서는…

func handleTap(sender: UIGestureRecognizer) {
    
}

당신은 …을 가져야 합니다.

let gesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))

func와 제스처가 뷰 컨트롤러 내에 있다고 가정합니다.modelObj 속성 / 아입니다에서 . 제스처 인식기로 전달할 필요가 없습니다. 에서 참조하면 됩니다.handleTap

1단계: 보낸 사람의 사용자 지정 개체를 만듭니다.

2단계: 보낸 사람의 사용자 지정 개체에서 변경할 속성 추가

3단계: 수신 기능의 발신인을 사용자 지정 개체에 입력하고 해당 속성에 액세스합니다.

예: 문자열 또는 사용자 지정 개체를 보내고 싶은 경우 버튼을 클릭하면

1단계: 만들기

class CustomButton : UIButton {

    var name : String = ""
    var customObject : Any? = nil
    var customObject2 : Any? = nil

    convenience init(name: String, object: Any) {
        self.init()
        self.name = name
        self.customObject = object
    }
}

2-a단계: 스토리보드에서도 사용자 지정 클래스 설정

enter image description here

2-b단계: 다음과 같이 사용자 지정 클래스를 사용하여 해당 버튼의 IBOutlet을 만듭니다.

@IBOutlet weak var btnFullRemote: CustomButton!

3단계: 보낸 사람의 사용자 지정 개체에서 변경할 속성 추가

btnFullRemote.name = "Nik"
btnFullRemote.customObject = customObject
btnFullRemote.customObject2 = customObject2
btnFullRemote.addTarget(self, action: #selector(self.btnFullRemote(_:)), for: .touchUpInside)

4단계: 수신 기능에서 발신자를 사용자 지정 개체에 입력하고 해당 속성에 액세스합니다.

@objc public func btnFullRemote(_ sender: Any) {

var name : String = (sender as! CustomButton).name as? String

var customObject : customObject = (sender as! CustomButton).customObject as? customObject

var customObject2 : customObject2 = (sender as! CustomButton).customObject2 as? customObject2

}

스위프트 5.0 iOS 13

Ninad의 훌륭한 답변에 동의합니다.여기 제 2센트짜리 동전이 있습니다. 똑같지만 다른 기술입니다. 최소한의 버전입니다.

사용자 지정 클래스를 만들고, 코드를 가능한 한 유지/유지할 수 있도록 열거형을 던집니다.

enum Vs: String {
  case pulse = "pulse"
  case precision = "precision"
} 

class customTap: UITapGestureRecognizer {
  var cutomTag: String?
}

사용자 정의 변수를 막대에 설정해야 합니다.여기서 간단한 레이블을 사용하면, 마지막 줄에 주의하십시오. 중요한 레이블은 일반적으로 상호 작용하지 않습니다.

let precisionTap = customTap(target: self, action: #selector(VC.actionB(sender:)))
precisionTap.customTag = Vs.precision.rawValue
precisionLabel.addGestureRecognizer(precisionTap)
precisionLabel.isUserInteractionEnabled = true

그리고 이를 사용하여 작업을 설정합니다. 참고로 순수 열거형을 사용하고 싶었지만 목표 C에서 지원하지 않기 때문에 기본 유형인 String을 사용합니다.

@objc func actionB(sender: Any) {
// important to cast your sender to your cuatom class so you can extract your special setting.
  let tag = customTag as? customTap
  switch tag?.sender {
    case Vs.pulse.rawValue:
      // code
    case Vs.precision.rawValue:
      // code
    default:
      break
    }
}

그게 다야.

cell.btn.tag = indexPath.row //setting tag
cell.btn.addTarget(self, action: #selector(showAlert(_ :)), for: .touchUpInside)

@objc func showAlert(_ sender: UIButton){
  print("sender.tag is : \(sender.tag)")// getting tag's value
}

UITapGesture Recognizer의 사용자 지정 클래스를 생성하기만 하면 됩니다 =>

import UIKit

class OtherUserProfileTapGestureRecognizer: UITapGestureRecognizer {

    let userModel: OtherUserModel    
    init(target: AnyObject, action: Selector, userModel: OtherUserModel) {
        self.userModel = userModel
        super.init(target: target, action: action)
    }
}

그런 다음 UIImageView 확장을 만듭니다 =>

import UIKit

    extension UIImageView {
    
        func gotoOtherUserProfile(otherUserModel: OtherUserModel) {
            isUserInteractionEnabled = true
            let gestureRecognizer = OtherUserProfileTapGestureRecognizer(target: self, action: #selector(self.didTapOtherUserImage(_:)), otherUserModel: otherUserModel)
            addGestureRecognizer(gestureRecognizer)
        }
        
        @objc internal func didTapOtherUserImage(_ recognizer: OtherUserProfileTapGestureRecognizer) {
            Router.shared.gotoOtherUserProfile(otherUserModel: recognizer.otherUserModel)
        }
    }

이제 =>처럼 사용하세요.

self.userImageView.gotoOtherUserProfile(otherUserModel: OtherUserModel)

사용할 수 있습니다.UIAction대신:

self.imageView.addAction(UIAction(identifier: UIAction.Identifier("imageClick")) { [weak self] action in
    self?.handleTap(modelObj)
}, for: .touchUpInside)

언급URL : https://stackoverflow.com/questions/43251708/passing-arguments-to-selector-in-swift

반응형