1

3D Touch のピークとポップのプレビューが埋め込まれている UIScrollView をスウィズルしようとしています (Reveal アプリを介して UIScrollView であることはわかっています)。

ユーザーがこのスクロール ビュー/3D タッチ プレビューで指を動かすたびに知りたいです。

次のようにスウィズルしてみました。

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];

        SEL originalSelector = @selector(setContentOffset:);
        SEL swizzledSelector = @selector(xxx_setContentOffset:);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

#pragma mark - Method Swizzling

- (void)xxx_setContentOffset:(CGPoint)offset {
    [self xxx_setContentOffset:offset];

    NSLog(@"yes");

}

しかし、画面上で指をスライドさせて数百回の呼び出しがあるはずのときに、「はい」と呼ぶのは1回か2回だけです。

私はこれを間違ってスウィズしていますか?

4

1 に答える 1

0

スクロールビュー自体が「セッター」を呼び出すかどうかはわかりません。そのため、必ずしもコールバックを取得するとは限りません。

contentOffset プロパティで KVO を介してスクロールビューに「フローティング」ビューを作成しましたが、期待どおりに呼び出されます。あなたの場合、同じメカニズムを使用できるかもしれません:

        /**
         *  We are using KVO to offset the background image view
        */

        [self addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"contentOffset"]) {
        _bgImageView.frame = CGRectMake(self.contentOffset.x,0, self.frame.size.width, self.frame.size.height);
    }
}

しかし、参考までに、私はこのようにスウィズルしています:

+(void)load {
    NSArray *selectors = @[NSStringFromSelector(@selector(setText:)),...];

    for (NSString *name in selectors) {
        SEL originalSelector = NSSelectorFromString(name);
        SEL swizzledSelector = NSSelectorFromString([NSString stringWithFormat:@"iio_swizzled_%@",name]);
        Method originalMethod = class_getInstanceMethod(self, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector);
        class_addMethod(self,
                        originalSelector,
                        class_getMethodImplementation(self, originalSelector),
                        method_getTypeEncoding(originalMethod));
        class_addMethod(self,
                        swizzledSelector,
                        class_getMethodImplementation(self, swizzledSelector),
                        method_getTypeEncoding(swizzledMethod));
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }

}

-(void)iio_swizzled_setText:(NSString *)text {
   ... do stuff
   // and if needed to call the original 
  [self iio_swizzled_setText:text];
}
于 2016-04-11T11:04:05.710 に答える