检测对 UIWebView 滚动视图内容大小的更改



我正在尝试在uiscrollview内容的底部设置一个Uiview,以便我将视图的位置设置为scrollview的contentsize高度。但是我的scrollview是uiwebview的一个子视图,因此,当加载图像时,内容更改的高度更改,而我的视图应位于滚动显示的底部。

因此,当ScrollView的内容更改更改时,我正在寻找一种通知的方式。我试图将其子类插入并更改设置器以发送nsnotification:

@implementation UIScrollView (Height)
-(void)setContentSize:(CGSize)contentSize
{
    _contentSize=contentSize;
    [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"scrollViewContentSizeChanged" object:nil]];
}
@end

但是在编译上,我会出现错误:

" _ objc_ivar _ $ _ uiscrollview._contentsize",从: - [uiscrollview(heigth)setContentsize:]在myclass.o中 LD:未在Architutection ARMV7

中找到符号

知道如何将设置器分类?

谢谢!

也许您可以使用键值观察(KVO)来检测内容大小的更改。我没有尝试过,但是代码应该看起来像这样:

static int kObservingContentSizeChangesContext;
- (void)startObservingContentSizeChangesInWebView:(UIWebView *)webView {
    [webView.scrollView addObserver:self forKeyPath:@"contentSize" options:0 context:&kObservingContentSizeChangesContext];
}
- (void)stopObservingContentSizeChangesInWebView:(UIWebView *)webView {
    [webView.scrollView removeObserver:self forKeyPath:@"contentSize" context:&kObservingContentSizeChangesContext];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if (context == &kObservingContentSizeChangesContext) {
        UIScrollView *scrollView = object;
        NSLog(@"%@ contentSize changed to %@", scrollView, NSStringFromCGSize(scrollView.contentSize));
    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

如果那不起作用,则可能需要浏览setContentSize:方法。方法swizzling可以让您的替换方法调用原始方法,这是将新内容大小传递到滚动视图所需的操作。

您可以在此处阅读有关方法的更多信息:http://www.mikeash.com/pyblog/friday-qa-2010-2010-01-29-method-replacement-for-for-fun-fun-and-profit.html

我认为这是最受欢迎的Swizzling代码:https://github.com/rentzsch/jrswizzle

您的方法是正确的一半。您肯定可以通过类别覆盖现有方法,尽管您正在访问类的IVAR。

在这种情况下,您需要的是方法:您覆盖setContentSize,同时介绍该方法的原始实现,因此您可以调用它以设置_contentSize值。

这是您可以使用的代码,并注释:

@implementation UIScrollView (Height)
// -- this method is a generic swizzling workhorse
// -- it will swap one method impl with another and keep the old one
// under your own impl name
+ (void)swizzleMethod:(SEL)originalSel andMethod:(SEL)swizzledSel {
  Method original = class_getInstanceMethod(self, originalSel);
  Method swizzled = class_getInstanceMethod(self, swizzledSel);
  if (original && swizzled)
     method_exchangeImplementations(original, swizzled);
  else
    NSLog(@"Swizzling Fault: methods not found.");
}    
//-- this is called on the very moment when the categoty is loaded
//-- and it will ensure the swizzling is done; as you see, I am swapping
//-- setContentSize and setContentSizeSwizzled;
+ (void)load {
  [self swizzleMethod:@selector(setContentSize:) andMethod:@selector(setContentSizeSwizzled:)];
}
//-- this is my setContentSizeSwizzled implementation;
//-- I can still call the original implementation of the method
//-- which will be avaiable (*after swizzling*) as setContentSizeSwizzled
//-- this is a bit counterintuitive, but correct!
- (void)setContentSizeSwizzled:(CGSize)contentSize
{
  [self setContentSizeSwizzled:contentSize];
  [[NSNotificationCenter defaultCenter] postNotification:[NSNotification    notificationWithName:@"scrollViewContentSizeChanged" object:nil]];
}
@end

希望它有帮助。

相关内容

  • 没有找到相关文章

最新更新