UIScrollView及其子类的嵌套联动

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UIScrollView及其子类的嵌套联动相关的知识,希望对你有一定的参考价值。

参考技术A 两个纵向滚动的视图可以同时识别拖拽手势才能根据偏移量控制是否可以滑动,当滑动的时候就可以分别在各自的scrollViewDidScroll方法中获取到各自的偏移量

赋予两个scrollView各自属性canScroll,通过通知传递参数控制联动。
⚠️控制联动,不能通过控制 scrollView.isScrollEnabled 来实现,否则到临界点会卡顿不流畅,通过控制 scrollView.contentOffset 实现。
父控制器

子控制器

切换分页,在横向拖动的过程中又进行了纵向拖动,此时我们希望视图不会上下跑,只是左右滚动

索引指示器可以用UIScrollView实现,也可以用UICollectionView实现,根据个人喜好,建议数据量多的话最好用UICollectionView了。
如果用UICollectionView实现,当手动滚动索引指示器,当把选中的索引滚出屏幕显示范围,再点选别的,此时可能会产生由于复用引发的崩溃和选中状态错乱,要进行判空处理,swift中可以设置cell为Optional可选型类型。

该控制器内的滚动视图可以是UIScrollView,也可以是UITableView,就可以将整个containerView部分添加到cell.contentView上,一样可以实现效果。

仅适用于类及其子类的属性

【中文标题】仅适用于类及其子类的属性【英文标题】:Properties for Class and Its Subclasses Only 【发布时间】:2011-05-14 22:29:09 【问题描述】:

是否可以定义仅对定义它们的类和该类的子类可用的属性?

换一种说法,有没有办法定义受保护的属性?

【问题讨论】:

【参考方案1】:

从技术上讲,没有。属性实际上只是方法,所有方法都是公共的。我们在 Objective-C 中“保护”方法的方式是不让其他人知道它们。

实际上,是的。您可以在类扩展中定义属性,并在主实现块中仍然@synthesize 它们。

【讨论】:

要被“保护”,类扩展接口需要在一个单独的头文件中被包含在类及其子类中。 据我所知,在基类接口扩展中声明的任何属性都不适用于子类——它们是私有的,不受保护的。请参阅此 SO 讨论:***.com/questions/5588799/… @Harkonian 如果您自己声明选择器,您可以随时调用它。除了简单地隐藏它的声明之外,没有像“保护”一个方法这样的东西。 Objective-C 没有受保护或私有方法的概念。仅限受保护的或私有的 ivars。【参考方案2】:

这可以通过使用包含在基类和子类的实现文件中的类扩展(而不是类别)来实现。

类扩展的定义类似于类别,但没有类别名称:

@interface MyClass ()

在类扩展中,您可以声明属性,这些属性将能够合成支持的 ivars(XCode > 4.4 自动合成 ivars 也适用于此)。

在扩展类中,您可以覆盖/优化属性(将只读更改为读写等),并添加对实现文件“可见”的属性和方法(但请注意,属性和方法并不是真正的私有的,仍然可以被选择器调用)。

其他人建议为此使用单独的头文件 MyClass_protected.h,但这也可以使用 #ifdef 在主头文件中完成,如下所示:

例子:

BaseClass.h

@interface BaseClass : NSObject

// foo is readonly for consumers of the class
@property (nonatomic, readonly) NSString *foo;

@end


#ifdef BaseClass_protected

// this is the class extension, where you define 
// the "protected" properties and methods of the class

@interface BaseClass ()

// foo is now readwrite
@property (nonatomic, readwrite) NSString *foo;

// bar is visible to implementation of subclasses
@property (nonatomic, readwrite) int bar;

-(void)baz;

@end

#endif

BaseClass.m

// this will import BaseClass.h
// with BaseClass_protected defined,
// so it will also get the protected class extension

#define BaseClass_protected
#import "BaseClass.h"

@implementation BaseClass

-(void)baz 
    self.foo = @"test";
    self.bar = 123;


@end

ChildClass.h

// this will import BaseClass.h without the class extension

#import "BaseClass.h"

@interface ChildClass : BaseClass

-(void)test;

@end

ChildClass.m

// this will implicitly import BaseClass.h from ChildClass.h,
// with BaseClass_protected defined,
// so it will also get the protected class extension

#define BaseClass_protected 
#import "ChildClass.h"

@implementation ChildClass

-(void)test 
    self.foo = @"test";
    self.bar = 123;

    [self baz];


@end

当您调用#import 时,它基本上会将 .h 文件复制粘贴到您要导入它的位置。 如果您有#ifdef,则只有在设置了具有该名称的#define 时,它才会包含其中的代码。

在您的 .h 文件中,您没有设置定义,因此任何导入此 .h 的类都不会看到受保护的类扩展。 在基类和子类 .m 文件中,在使用 #import 之前使用 #define,以便编译器包含受保护的类扩展。

【讨论】:

【参考方案3】:

你可以在子类实现中使用这样的语法。

@interface SuperClass (Internal)

@property (retain, nonatomic) NSString *protectedString;

@end

【讨论】:

【参考方案4】:

你可以使用一个类别来达到你的目的

@interface SuperClass (Protected)

@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIView *topMenuView;
@property (nonatomic, strong) UIView *bottomMenuView;

@end

在子类中,您将这个类别导入文件 .m

【讨论】:

以上是关于UIScrollView及其子类的嵌套联动的主要内容,如果未能解决你的问题,请参考以下文章

滚动其子uiscrollview时如何防止滚动uiscrollview?

缩放嵌套在 UIScrollView 中的子视图

仅适用于类及其子类的属性

UIScrollView 并检测其子视图的手势

UIScrollView 帮助

滚动 UIScrollView 会更改其子视图框架