【问题标题】:How do I properly observe the contentOffset property of my scrollView subclass?如何正确观察我的 scrollView 子类的 contentOffset 属性?
【发布时间】:2012-01-04 15:13:11
【问题描述】:

在我的 iOS 应用程序中,我正在观察我的 scrollView 子类的 contentOffset 属性的变化。我的观察者处理程序如下所示:

- (void)observeContentOffsetHandler:(id)aContentOffset {

    NSLog(@"%@", aContentOffset);

}

为了简单起见,我任意选择方法的参数作为id

我的 NSLog'ging 看起来像这样:

-[MyScrollView observeContentOffsetHandler:] [Line 111] NSPoint: {296, 375}
-[MyScrollView observeContentOffsetHandler:] [Line 111] NSPoint: {296, 389}
-[MyScrollView observeContentOffsetHandler:] [Line 111] NSPoint: {295, 401}
-[MyScrollView observeContentOffsetHandler:] [Line 111] NSPoint: {291, 415}

我需要使用 x 和 y 值,但我不知道如何获取它们。我尝试将 id 转换为 CGPoint,不。我尝试将参数更改为 CGPoint,不。

更新

它变得更深了。 @mgold 不高兴。以下是我设置观察的方式:

self.contentOffsetObserver = [[[Observer alloc] initWithTarget:self action:@selector(observeContentOffsetHandler:)] autorelease];
[self.myScrollViewSubclass addObserver:self.contentOffsetObserver forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:NULL];

Observer 是一个方便的类,我用来简化观察。注意观察者回调 observeContentOffsetHandler:。当我从当前更改此方法的签名时:

- (void)observeContentOffsetHandler:(id)aContentOffset

@mgold 对 CGPoint 的建议:

- (void)observeContentOffsetHandler:(CGPoint)aContentOffset

这是不正确的,因为 NSLog 显示的 aContentOffset 全部为零:

-[MyScrollController observeContentOffsetHandler:] [Line 74] aContentOffset 0 0
-[MyScrollController observeContentOffsetHandler:] [Line 74] aContentOffset 0 0
-[MyScrollController observeContentOffsetHandler:] [Line 74] aContentOffset 0 0
-[MyScrollController observeContentOffsetHandler:] [Line 74] aContentOffset 0 0

不知道我的举动是什么。

【问题讨论】:

    标签: ios uiscrollview key-value-observing cgpoint


    【解决方案1】:

    知道了。方法正确的签名是:

    - (void)observeContentOffsetHandler:(NSValue *)aContentOffset
    

    然后,CGPoint 的检索是微不足道的:

    CGPoint pt = [aContentOffset CGPointValue];
    

    干杯,
    道格

    【讨论】:

      【解决方案2】:

      因为你有一个 UIScrollView 子类,你可以访问 layoutSubViews
      每次 contentOffset 更改时都会调用它。

      这是在发生更改时获取更改的“正确方法”。不要使用 KVO 是的 contentOffset 是一个 CGPoint ......除非你在谈论 NSScrollView ......但即便如此基本的想法保持不变。

      覆盖 layoutSubviews....记得调用 super

      将您的 ViewController 注册为 scrollView 的委托并实现 scrollView:didScroll

      【讨论】:

      • 不确定您所说的正确是什么意思。有人可能会争辩说,带有与 UIView 子类的基本目的无关的功能的混乱 layoutSubviews 是糟糕的设计。我的观察将发生在控制器中,从 MVC 的角度来看,它更有意义。只是说......
      • 我以为你想在子类中做一些与 UI 相关的事情,因此 layoutSubviews。您的 viewController(管理滚动视图的那个)应该是滚动视图的委托并实现 scrollView:didScroll 这将在每次 contentOffset 更改时调用:) 并且它也不会破坏 MVC。
      • @AnimishH,过去我确实遵循了流行的 scrollViews 控制器处理 scrollViewDelegate 职责的方法。我现在很少这样做,使 scrollView 成为自己的代表。流行的方法倾向于用 scrollView 管理职责使控制器混乱,仔细检查后,scrollView 完全能够处理并且根本不涉及域逻辑。例如viewForZoomingInScrollView:在控制器中没有业务。那是查看管道代码而不是域代码。
      • layoutSubViews 属于UIScrollViewController 而不是UIScrollView。有人可能只想使用没有控制器的滚动视图,即因为它被嵌入到一个简单的UIViewController 的视图中..
      【解决方案3】:

      contentoffset 确实是一个CGPoint,它是一个带有CGFloats xy 的C 结构。就这么简单

      aContentOffset.x
      aContentOffset.y
      

      因为你是 UIScrollView 的子类,所以你也有 contentoffset 属性,只是说。

      【讨论】:

      • 谢谢。我确实可以直接使用 contentOffset,但是我正在做的观察的语义是不同的。干杯。
      • 行不通,因为 CGPoint 是一个标量而不是一个类。观察处理程序将类(id、NSValue* 等)作为其参数。
      猜你喜欢
      • 1970-01-01
      • 2017-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 2015-02-06
      • 2020-12-26
      • 1970-01-01
      相关资源
      最近更新 更多