UIKit の Private な UIGestureRecognizer その2
NSLog(@"%@", gestureRecognizer);
の出力結果って見辛いよねって事で、いい感じに調査をするために調査用のログ出力を試みてみる。
通常のログ出力
<UITextTapRecognizer: 0x7ff853734850; state = Possible; delaysTouchesEnded = NO; view = <MyTextField 0x7ff853725f30>; target= <(action=oneFingerTripleTap:, target=<UITextInteractionAssistant 0x7ff853724d50>)>; numberOfTapsRequired = 3>
から
UITextTapRecognizer
action=oneFingerTripleTap:
target=UITextInteractionAssistant
numberOfTapsRequired
numberOfTouchesRequired
あたりだけを表示したい。
ここで問題が。
UIControl
の場合
- (NSSet *)allTargets; - (NSArray *)actionsForTarget:(id)target forControlEvent:(UIControlEvents)controlEvent;
というメソッドによって簡単にターゲットとアクションが取得できるけど、UIGestureRecognizer
の場合はこれらのメソッドが存在していない。
そこでこの記事で書いた方法で Private なメソッドやインスタンス変数を調べてみる。
結果は以下
// Method List of UIGestureRecognizer reset description dealloc setDelegate: setDelaysTouchesBegan: _setRequiresSystemGesturesToFail: locationInView: _physicalButtonsBegan:withEvent: _isDirty touchesCancelled:withEvent: ignoreTouch:forEvent: _updateGestureStateWithEvent:buttonEvent:afterDelay: _queueForResetIfFinished _ignorePhysicalButton:forEvent: _physicalButtonsEnded:withEvent: _physicalButtonsCancelled:withEvent: setView: touchesBegan:withEvent: touchesMoved:withEvent: touchesEnded:withEvent: _setDirty _requiresSystemGesturesToFail removeTarget:action: setDelaysTouchesEnded: requireGestureRecognizerToFail: numberOfTouches _activeTouchesForEvent: _isRecognized setCancelsTouchesInView: canBePreventedByGestureRecognizer: canPreventGestureRecognizer: addTarget:action: _delegateShouldReceiveTouch: requireOtherGestureToFail: locationOfTouch:inView: _connectInterfaceBuilderEventConnection: _setAcceptsFailureRequiments: _resetGestureRecognizer delaysTouchesBegan _briefDescription _shouldBeRequiredToFailByGestureRecognizer: _clearReferencesToRelatedGesture: _enqueueDelayedTouchesToSend _clearUpdateTimer _shouldBegin _isFriendWithGesture: _enqueueDelayedTouchToSend: _delayTouch:forEvent: _clearDelayedTouches _willBeginAfterSatisfyingFailureRequirements _delayTouchesForEvent: _updateGestureWithEvent:buttonEvent: _shouldReceiveTouch: _affectedByGesture: _delegateCanPreventGestureRecognizer: _addFailureDependent: _removeFailureDependent: _appendDescriptionToString:atLevel:includingDependencies: cancelsTouchesInView delaysTouchesEnded _appendSubclassDescription: _appendDescription:forDependencies:toString:atLevel: _failureMap _setFailureMap: _delayedTouches _hasTargets _shouldRequireFailureOfGestureRecognizer: shouldRequireFailureOfGestureRecognizer: shouldBeRequiredToFailByGestureRecognizer: _centroidOfTouches:excludingEnded: _distanceBetweenTouches: _touchWasCancelled: _requiresGestureRecognizerToFail: _delayedUpdateGesture _resetIfFinished _depthFirstViewCompare: _addFriendGesture: _isExcludedByGesture: _cancelRecognition _exclude _addDynamicFailureDependent: _addDynamicFailureRequirement: removeFailureRequirement: _failureRequirementCompleted:withEvent: _acceptsFailureRequirements _detach state encodeWithCoder: initWithCoder: setState: delegate _invalidate init initWithTarget:action: view isEnabled setEnabled: // Property List of UIGestureRecognizer state delegate enabled view cancelsTouchesInView delaysTouchesBegan delaysTouchesEnded // Ivar List of UIGestureRecognizer _targets _delayedTouches _view _updateEvent _updateButtonEvent _delegate _friends _state _gestureFlags _failureRequirements _failureDependents _dynamicFailureRequirements _dynamicFailureDependents _failureMap
Private なインスタンス変数に _targets
というドンピシャっぽいものがあった。
これを KVO を使って
NSLog(@"%@", [gestureRecognizer valueForKey:@"targets"]);
このようにしてインスタンス変数を取得してログ出力してみると以下のような結果が得られた。
( "(action=oneFingerTripleTap:, target=<UITextInteractionAssistant 0x7f950bf1af90>)" )
何かしらのクラスの配列になっているっぽい。 そこで今度は以下のようにしてその何かしらのクラスの実態を探る。
この記事のクラス階層を表示する function も加えて以下のようにする。
id object = [[gestureRecognizer valueForKey:@"targets"] firstObject]; Class cls = [object class]; PrintClassHierarchy(cls); PrintMethodList(cls); PrintPropertyList(cls); PrintIvarList(cls);
出力は以下
// Class Hierarchy of UIGestureRecognizerTarget UIGestureRecognizerTarget : NSObject // Method List of UIGestureRecognizerTarget description // Property List of UIGestureRecognizerTarget // Ivar List of UIGestureRecognizerTarget _target _action
どうやら配列に格納されているのは NSObject
のサブクラスの UIGestureRecognizerTarget
という Private なクラスで、_target
と _action
という Private なインスタンス変数を持っているらしい。
target と action の方は UIGestureRecognizer
のイニシャライザ
- (instancetype)initWithTarget:(id)target action:(SEL)action;
と同じく id型 と SEL型 だろうと推測できる。
descriptionメソッドの返り値も NSString *
だと推測できるので、ここまでで分かったことをまとめるとこうなる。
続く