Ios 在superView上执行选择器
我有一个Ios 在superView上执行选择器,ios,objective-c,uiscrollview,selector,Ios,Objective C,Uiscrollview,Selector,我有一个UICollectionView,它使用-(void)scrollViewDidScroll:(UIScrollView*)scrollView来确定用户何时滚动到底部 myUICollectionView的所有者有一个向服务器发送命令并请求更多数据的方法 我要做的是从我的UICollectionView,特别是从scrollViewDidScroll中对所有者(我的viewcontroller)执行选择器 我尝试使用以下代码执行此操作: - (void)scrollViewDidScr
UICollectionView
,它使用-(void)scrollViewDidScroll:(UIScrollView*)scrollView
来确定用户何时滚动到底部
myUICollectionView
的所有者有一个向服务器发送命令并请求更多数据的方法
我要做的是从我的UICollectionView
,特别是从scrollViewDidScroll
中对所有者(我的viewcontroller)执行选择器
我尝试使用以下代码执行此操作:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat offsetY = scrollView.contentOffset.y;
CGFloat contentHeight = scrollView.contentSize.height;
if (offsetY > contentHeight - scrollView.frame.size.height)
{
[[self superView] performSelector:@selector(onScrolledToBottom) withObject:nil];
}
}
注意:CrolledToBottom上的选择器是myUICollectionView
的SEL
属性
我收到的错误说明:
-[UIView onScrolledToBottom]: unrecognized selector sent to instance 0x7fc641e76e00
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView onScrolledToBottom]: unrecognized selector sent to instance 0x7fc641e76e00'
编辑
我已经精简了我的代码以适应这个问题
我的ViewController.m中有以下内容
....
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initCollectionView];
}
....
- (void) getMoreInfo{
NSLog(@"Getting more info");
}
- (void) initCollectionView{
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(50.0, 60.0);
flowLayout.sectionInset = UIEdgeInsetsMake(20, 0, 20, 0);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
flowLayout.headerReferenceSize = CGSizeMake(320.f, 30.f);
myCollectionView *mVC = [myCollectionView alloc] init: self.view: flowLayout: @selector(getMoreInfo)];
}
....
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initCollectionView];
}
....
- (void) getMoreInfo{
NSLog(@"Getting more info");
}
- (void) initCollectionView{
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(50.0, 60.0);
flowLayout.sectionInset = UIEdgeInsetsMake(20, 0, 20, 0);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
flowLayout.headerReferenceSize = CGSizeMake(320.f, 30.f);
myCollectionView *mVC = [myCollectionView alloc] initWithParentViewController:self layout:flowLayout selector:@selector(getMoreInfo)];
}
对于我的myCollectionView
而言,.h
和.m
文件如下所示:
#import <UIKit/UIKit.h>
@interface myCollectionView : UICollectionView<UIScrollViewDelegate, UICollectionViewDelegate, UICollectionViewDataSource>{
UIView *parentView;
SEL onScrolledToBottom;
}
@property UIView *parentView;
@property SEL onScrolledToBottom;
- (id)init: (UIView*) parent: (UICollectionViewLayout *)layout: (SEL)onScrolledToBottomSEL;
@end
collectionView.parentView
将是ViewController.view
,它完全是一个UIView
,没有名为onScrolledToBottom
的方法
这里有一个方法,如果我对你想要的是正确的,但是这确实是一个非常糟糕的方法
在ViewController.m中
....
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initCollectionView];
}
....
- (void) getMoreInfo{
NSLog(@"Getting more info");
}
- (void) initCollectionView{
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(50.0, 60.0);
flowLayout.sectionInset = UIEdgeInsetsMake(20, 0, 20, 0);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
flowLayout.headerReferenceSize = CGSizeMake(320.f, 30.f);
myCollectionView *mVC = [myCollectionView alloc] init: self.view: flowLayout: @selector(getMoreInfo)];
}
....
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initCollectionView];
}
....
- (void) getMoreInfo{
NSLog(@"Getting more info");
}
- (void) initCollectionView{
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(50.0, 60.0);
flowLayout.sectionInset = UIEdgeInsetsMake(20, 0, 20, 0);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
flowLayout.headerReferenceSize = CGSizeMake(320.f, 30.f);
myCollectionView *mVC = [myCollectionView alloc] initWithParentViewController:self layout:flowLayout selector:@selector(getMoreInfo)];
}
在myCollectionView.h中
#import <UIKit/UIKit.h>
@interface myCollectionView : UICollectionView<UIScrollViewDelegate, UICollectionViewDelegate, UICollectionViewDataSource>{
UIViewController *_parentViewController;
SEL _onScrolledToBottom;
}
@property(weak) UIViewController *parentViewController;
@property SEL onScrolledToBottom;
- (id)initWithParentViewController:(UIView *)parentViewController layout:(UICollectionViewLayout *)layout selector:(SEL)onScrolledToBottomSEL;
@end
警告:
- 在
MVC
中,应该有一个控制器来实现
协议,而不是视图
- 类名的第一个字符必须大写,您应该使用
MyCollectionView
而不是MyCollectionView
作为类名
- 当使用属性时,LLVM编译器将自动生成一个成员变量,无需再次声明
- 在这种情况下,使用
协议委托
是最好的方法
集合视图。父视图将是ViewController.view
,它完全是一个UIView
,没有名为onScrolledTobotom
的方法
这里有一个方法,如果我对你想要的是正确的,但是这确实是一个非常糟糕的方法
在ViewController.m中
....
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initCollectionView];
}
....
- (void) getMoreInfo{
NSLog(@"Getting more info");
}
- (void) initCollectionView{
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(50.0, 60.0);
flowLayout.sectionInset = UIEdgeInsetsMake(20, 0, 20, 0);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
flowLayout.headerReferenceSize = CGSizeMake(320.f, 30.f);
myCollectionView *mVC = [myCollectionView alloc] init: self.view: flowLayout: @selector(getMoreInfo)];
}
....
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initCollectionView];
}
....
- (void) getMoreInfo{
NSLog(@"Getting more info");
}
- (void) initCollectionView{
UICollectionViewFlowLayout* flowLayout = [[UICollectionViewFlowLayout alloc]init];
flowLayout.itemSize = CGSizeMake(50.0, 60.0);
flowLayout.sectionInset = UIEdgeInsetsMake(20, 0, 20, 0);
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
flowLayout.headerReferenceSize = CGSizeMake(320.f, 30.f);
myCollectionView *mVC = [myCollectionView alloc] initWithParentViewController:self layout:flowLayout selector:@selector(getMoreInfo)];
}
在myCollectionView.h中
#import <UIKit/UIKit.h>
@interface myCollectionView : UICollectionView<UIScrollViewDelegate, UICollectionViewDelegate, UICollectionViewDataSource>{
UIViewController *_parentViewController;
SEL _onScrolledToBottom;
}
@property(weak) UIViewController *parentViewController;
@property SEL onScrolledToBottom;
- (id)initWithParentViewController:(UIView *)parentViewController layout:(UICollectionViewLayout *)layout selector:(SEL)onScrolledToBottomSEL;
@end
警告:
- 在
中,应该有一个MVC
控制器来实现 协议,而不是视图
- 类名的第一个字符必须大写,您应该使用
而不是MyCollectionView
作为类名MyCollectionView
- 当使用属性时,LLVM编译器将自动生成一个成员变量,无需再次声明
- 在这种情况下,使用
是最好的方法协议委托
- 您得到的是superview,而不是父控制器,这就是一个。第二,你不应该这样做。相反,使用协议并将控制器作为委托传递给自定义collectionview
@protocol MyCollectionViewScrollProtocol <NSObject>
- (void)scrolledToBottom;
@end
不要忘记从控制器设置委托属性
按OP编辑: 控制器应在
.h
文件中包含以下代码:
#import <UIKit/UIKit.h>
@protocol ViewControllerProtocol <NSObject>
- (void) Pong;
@end
@interface ViewController : UIViewController <ViewControllerProtocol>
@end
#import <Foundation/Foundation.h>
#import "ViewController.h"
@interface myUnit : NSObject {
}
@property (weak, nonatomic) id <ViewControllerProtocol> linkToController;
- (void)Ping;
@end
#import "myUnit.h"
#import "ViewController.h"
@implementation myUnit
- (void) Ping {
NSLog(@"Ping");
[self.linkToController Pong];
}
@end
想要访问控制器的装置需要在.h
文件中包含以下代码:
#import <UIKit/UIKit.h>
@protocol ViewControllerProtocol <NSObject>
- (void) Pong;
@end
@interface ViewController : UIViewController <ViewControllerProtocol>
@end
#import <Foundation/Foundation.h>
#import "ViewController.h"
@interface myUnit : NSObject {
}
@property (weak, nonatomic) id <ViewControllerProtocol> linkToController;
- (void)Ping;
@end
#import "myUnit.h"
#import "ViewController.h"
@implementation myUnit
- (void) Ping {
NSLog(@"Ping");
[self.linkToController Pong];
}
@end
你得到的是superview而不是父控制器,就是这样。第二,你不应该这样做。相反,使用协议并将控制器作为委托传递给自定义collectionview
@protocol MyCollectionViewScrollProtocol <NSObject>
- (void)scrolledToBottom;
@end
不要忘记从控制器设置委托属性
按OP编辑: 控制器应在
.h
文件中包含以下代码:
#import <UIKit/UIKit.h>
@protocol ViewControllerProtocol <NSObject>
- (void) Pong;
@end
@interface ViewController : UIViewController <ViewControllerProtocol>
@end
#import <Foundation/Foundation.h>
#import "ViewController.h"
@interface myUnit : NSObject {
}
@property (weak, nonatomic) id <ViewControllerProtocol> linkToController;
- (void)Ping;
@end
#import "myUnit.h"
#import "ViewController.h"
@implementation myUnit
- (void) Ping {
NSLog(@"Ping");
[self.linkToController Pong];
}
@end
想要访问控制器的装置需要在.h
文件中包含以下代码:
#import <UIKit/UIKit.h>
@protocol ViewControllerProtocol <NSObject>
- (void) Pong;
@end
@interface ViewController : UIViewController <ViewControllerProtocol>
@end
#import <Foundation/Foundation.h>
#import "ViewController.h"
@interface myUnit : NSObject {
}
@property (weak, nonatomic) id <ViewControllerProtocol> linkToController;
- (void)Ping;
@end
#import "myUnit.h"
#import "ViewController.h"
@implementation myUnit
- (void) Ping {
NSLog(@"Ping");
[self.linkToController Pong];
}
@end
您的“myCollectionView”应该有一个委托(您必须为此创建一个协议),并使用以下方法:
- (void)myCollectionViewDidScrollToBottom:(myCollectionView *)collectionView
按照约定,视图将自身传递给此方法(就像任何tableView委托方法一样)。然后在initCollectionView
之后的myCollectionView*mVC=[myCollectionView alloc]init…
中,您必须将此委托设置为当前视图控制器并实现该方法
mVC.delegate = self;
...
some other place in code
...
- (void)myCollectionViewDidScrollToBottom:(myCollectionView *)collectionView {
//do what's need to be done ;)
}
现在,您的“myCollectionView”不在乎它在哪里,也不在乎“谁”在哪里。任何想使用它的人都可以实现这个方法,并成为该视图的委托人,使用任何自定义逻辑。也就是说,在这个方法中,您可以调用任何必需的方法和任何其他东西
工作原理:
- (void)myCollectionViewDidScrollToBottom:(myCollectionView *)collectionView
按照约定,视图将自身传递给此方法(就像任何tableView委托方法一样)。然后在initCollectionView
之后的myCollectionView*mVC=[myCollectionView alloc]init…
中,您必须将此委托设置为当前视图控制器并实现该方法
mVC.delegate = self;
...
some other place in code
...
- (void)myCollectionViewDidScrollToBottom:(myCollectionView *)collectionView {
//do what's need to be done ;)
}
现在,您的“myCollectionView”不在乎它在哪里,也不在乎“谁”在哪里。任何想使用它的人都可以实现这个方法,并成为该视图的委托人,使用任何自定义逻辑。也就是说,在这个方法中,您可以调用任何必需的方法和任何其他东西
工作原理:
:)首先我想对大家说声谢谢 我通读了你们写的所有东西,我受到了启发 特别是Stanislav Ageev的回答
您得到的是superview而不是父控件