我正在尝试在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
希望它有帮助。