Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在superView上执行选择器_Ios_Objective C_Uiscrollview_Selector - Fatal编程技术网

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
来确定用户何时滚动到底部

my
UICollectionView
的所有者有一个向服务器发送命令并请求更多数据的方法

我要做的是从我的
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上的选择器
是my
UICollectionView
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”不在乎它在哪里,也不在乎“谁”在哪里。任何想使用它的人都可以实现这个方法,并成为该视图的委托人,使用任何自定义逻辑。也就是说,在这个方法中,您可以调用任何必需的方法和任何其他东西

      工作原理:

    • 向下滚动时查看通知其委托此事件
    • 委托处理所有需要执行的逻辑
    • :)

      您的“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而不是父控件