프로그래밍 방식으로 터치 이벤트를 UIButton에 가짜로 만드는 방법은 무엇입니까?


183

나는 몇 가지 단위 테스트를 작성하고 있으며이 특정 응용 프로그램의 특성으로 인해 UI체인을 최대한 높이 올리는 것이 중요 합니다. 그래서 내가하고 싶은 것은 사용자가 버튼을 누른 것처럼 프로그래밍 방식으로 버튼 누름을 트리거하는 것 GUI입니다.

(예, 예 . 셀렉터를 호출 할 수IBAction있지만이 특정 응용 프로그램의 특성상 실제 버튼 누름을 가짜 IBAction로 지정하여 버튼 자체에서 호출되도록하는 것이 중요 합니다.)

이 작업을 수행하는 데 선호되는 방법은 무엇입니까?


액션 메서드를 직접 호출하는 대신 버튼 터치를 위조하는 것이 중요한 이유를 설명해 주시겠습니까? 실질적인 차이는 없습니다.
Jasarien

1
@Jasarien : 글쎄요, 차이가 있기 때문입니다! ;) 내 응용 프로그램에서 여러 버튼이 동일한 동작 방법을 사용하고 버튼의 태그를 기반으로 동작 방법을 구문 분석합니다. 따라서 단위 테스트는 방법을 통해 하나의 특정 코드 경로를 테스트하는 것 외에도 (a) 모두 테스트해야하며 (b) 버튼이 올바르게 연결되어 있는지 확인해야합니다. 또한 단위 테스트를 텍스트 파일에서 다음과 같이 텍스트 파일의 줄로 정의 할 수 있으므로 단위 테스트 스위트를 멋지게 추상화합니다. 누르는 버튼입니다.
Olie

액션 메소드에 (id) 송신자 매개 변수가 없습니까? 메소드를 호출하고 버튼을 발신자로 전달할 수 없습니까?
Jasarien

3
때문에 내 테스트 장치의 추상적 인 성격, 나는하지 않습니다 알고 필요가 특정 버튼을 촉구 할 수있는 방법을. 나는 버튼을 파고 그것을 얻을 수 있다고 생각하지만 sendActionsForControlEvents를 수행하면 오류가 발생할 가능성이 적고이 모든 것을 수행하고 테스트를 추상화하고 디자인에 적합하게 유지합니다.
Olie

답변:


459

그것은 밝혀졌다

[buttonObj sendActionsForControlEvents: UIControlEventTouchUpInside];

이 경우에 내가 필요한 것을 정확히 얻었습니다.

편집 : 사용자 프레스와 비슷한 결과를 얻으려면 주 스레드 에서이 작업을 수행하는 것을 잊지 마십시오.


스위프트 3의 경우 :

buttonObj.sendActions(for: .touchUpInside)


전화 [myController myActionMethod:myButton1];

11
귀하의 의견 답변에는 큰 제한이 있습니다;)
Dan Rosenstark

@Jasarien은 터치 이벤트를 등록 된 모든 대상 (리스너)에 전송하므로 상당히 다릅니다.
htafoya

2
불행히도, 이것들 중 어느 것도 항상 작동하지 않을 것입니다-그들은 예를 들어 탭 제스처를 갖는 것보다는 UIControl 인 수신기에 의존합니다.
tooluser

1
@ChenLiYong, 하나의 이유는 myActionMethod:공개되지 않은 것이므로 직접 호출 할 수 없습니다.
Iulian Onofrei

50

Swift에 대한이 답변의 업데이트

buttonObj.sendActionsForControlEvents(.TouchUpInside)

편집 : 스위프트 3 업데이트

buttonObj.sendActions(for: .touchUpInside)

1
buttonObj.sendActionsForControlEvents (.TouchUpInside)는 훨씬 더 스위프트 스타일입니다.)
Sajjon

1
실행 루프를 지원하지 않고 XCTestCase에서 버튼을 만들면 이것이 작동하지 않는다고 생각합니다.
CopperCash

6

이런 종류의 테스트를 원한다면 iOS 4의 UI 자동화 지원을 좋아할 것입니다. 문서 (특히 시작하기 부분)가 약간 있지만 JavaScript를 작성하여 버튼 누름 등을 상당히 쉽게 시뮬레이션 할 수 있습니다 부족한.


1
그래,의 물건을 냉각,하지만 난하지 악기를 통해 응용 프로그램 내에서 그것을 할 노력하고있어 (즉, 당신이 의미하는 방법 인 경우.)
Olie

인스트루먼트는 앱과 함께 실행됩니다. 앱이 여전히 실행 중이며 기기는 터치를 시뮬레이션합니다.
Jeff Kelley

6
계측기를 이해합니다. Jeff-제가 말하는 것은 : 랩탑이나 XCode 또는 인스트루먼트를 사용하지 않고도 장치 테스트를 주머니에서 장치에서 실행하고 싶습니다. 아니면 기기에서 계측기를 실행하는 비결을 알고 있습니까? ;)
Olie

6

스위프트 3 :

self.btn.sendActions(for: .touchUpInside)

3
이것은 단지 더 높은 점수의 답변을 반복합니다.
Pang

5

이 경우에서 UIButton파생됩니다 UIControl. 이것은에서 파생 된 객체에 적용됩니다 UIControl.

UIBarButtonItem특정 사용 사례에서 " "작업 을 재사용하고 싶었습니다 . 여기에 UIBarButtonItem방법을 제공하지 않습니다sendActionsForControlEvents:

그러나 다행히도 UIBarButtonItem대상 및 동작에 대한 속성이 있습니다.

 if(notHappy){        
         SEL exit = self.navigationItem.rightBarButtonItem.action;
         id  world = self.navigationItem.rightBarButtonItem.target;
         [world performSelector:exit];
 }

여기는 rightBarButtonItem유형 UIBarButtonItem입니다.


UIBarButtonItem을 사용하는 경우 [self doAction : self.navigationItem.rightBarButtonItem]; //-doAction :은 self.navigationItem.rightBarButtonItem의 전환 작업 이름입니다.
c0ming


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.