成员引用基类型 'Class' 不是结构或联合 - Fixit 是否引导我朝着正确的方向前进?

Member reference base type 'Class' is not a structure or union - has the Fixit led me in the right direction?

我正在尝试制作一个 delegate,它将在一个名为 SGView 的自定义 UIView 中从 UIButtons 发送消息,但我有点不知所云错误信息。我最近学会了如何获得 .

SGView 包含一个 class 方法,将多个 UIButtons 排列成一个圆圈,旨在供不同的 UIViews. 使用。我现在通过将 @protocol@property 添加到 class 方法声明

来声明 delegate

像这样...

SGView.h

#import <UIKit/UIKit.h>

@protocol SGViewDelegate <NSObject>
    -(void)buttonPressed:(UIButton*)button;
@end

@interface SGView : UIView {
    }
    +(id)circleOfButtons:(int)buttonCount buttonSize:(CGFloat)buttonSize circleRadius:(CGFloat)circleRadius;

@property (assign) id<SGViewDelegate> delegate;

@end

SGView.m本质上是这样的

#import "SGView.h"

    @implementation SGView : UIView

    +(id)circleOfButtons:(int)buttonCount buttonSize:(CGFloat)buttonSize circleRadius:(CGFloat)circleRadius
    {
    UIView *multipleViews       = [self new];

    // … circular geometry …

    [circleButton addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];

    [multipleViews addSubview:circleButton];
    }
    return multipleViews;
    }
    @end

我在上面的目标动作语句中将目标从self更改为self.delegate的那一刻, Xcode报三个错误

Definition of 'objc_class' must be imported from module 'ObjectiveC.runtime' before it is required

No member named 'delegate' in 'struct objc_class'

Member reference type 'struct objc_class *' is a pointer; did you mean to use '->'?

Xcode 为最后一个

提供了 Fixit
    Fixit Replace”.” with “->”

通过接受 Fixit,我删除了三个问题并引入了另一个

Member reference base type 'Class' is not a structure or union

如果 Fixit 引导我朝着正确的方向前进,那么接下来我应该做什么?

在回到 Apple documentation and these tutorials 试图解决它之前,我需要问这个问题来弄清楚这个看似简单的问题。非常感谢任何帮助。谢谢。

解决方案

这可以在我对自己问题的回答中找到。

将 class 方法更改为实例方法似乎解决了我的问题。

这涉及将 class 方法 +(id)circleOfButtons:... etc 变成 .m.h 文件中的实例方法 (-(id)circleOfButtons:... etc)。还需要将父 UIView 中的调用从

更改为
    SGView *sgView              = [SGView circleOfButtons:count buttonSize:size circleRadius:radius];

    SGView *sgView              = [[SGView alloc] circleOfButtons:count buttonSize:size circleRadius:radius];

并将 SGView 中的声明从

更改为
    UIView *multipleViews       = [self new];

    UIView *multipleViews       = [[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds];

SGView 现在可以从不同的 UIViews 中重复使用,这些 UIViews 改变了排列成圆圈的 UIButtons 的数量和大小。 SGView 中的委托还允许每个按钮将标记消息发送到另一个 class 中的方法 - 在我的例子中是 ViewController.

完整清单包含在下面,我欢迎其他具有更多 OO 编程经验的人提出建议或改进。

ViewController.h

#import <UIKit/UIKit.h>

    @interface ViewController : UIViewController <UIContentContainer> {
    }
@end

ViewController.m

#import "ViewController.h"
#import "FamilyView.h"

@interface ViewController ()

@end

@implementation ViewController

    - (void)viewDidLoad                                             {
    [super viewDidLoad];

    NSLog(@"load FamilyView");

    CGRect rect             = [UIScreen mainScreen].bounds;
    float  statusBarHeight  = [[UIApplication sharedApplication] statusBarFrame].size.height;
    CGRect screenFrame      = CGRectMake(0, statusBarHeight, rect.size.width, rect.size.height - statusBarHeight);
    self.view               = [[UIView alloc] initWithFrame: screenFrame];

    FamilyView *cv          = [[FamilyView alloc]initWithFrame:screenFrame];
    [self.view addSubview:cv];    
}


    - (void)buttonPressed:(UIButton*)button                          {
    NSLog(@"Button %ld clicked.", (long int)[button tag]);

    switch (button.tag) {
        case 1:
        //            [self goToFamily1];
            break;
        case 2:
        //            [self goToFamily2];
            break;
        case 3:
        //            [self goToFamily3];
            break;
        case 4:
        //            [self goToFamily4];
            break;
        case 5:
        //            [self goToFamily5];
            break;
        default:
        //            [self goToHelp];
            break;
        }
    }
    @end

FamilyView.h

#import <UIKit/UIKit.h>
#import "ViewController.h"
#import "SGView.h"

    @interface FamilyView : UIView {
    }
@end

FamilyView.m

#import <UIKit/UIKit.h>
#import "FamilyView.h"
#import "SGView.h"

    @implementation FamilyView : UIView

    - (id)initWithFrame:(CGRect)frame {
    self                                    = [super initWithFrame:[UIScreen mainScreen].bounds];
    if (self) {

    self.backgroundColor                    = [UIColor lightGrayColor];

    int     count                           = 5;  //16;
    CGFloat size                            = 80; //41;
    CGFloat radius                          = 68; //105;

    SGView *sgView                          = [[SGView alloc] circleOfButtons:count buttonSize:size circleRadius:radius];
    [self addSubview:sgView];
    }
    return self;
}
@end

SGView.h

#import <UIKit/UIKit.h>

    @protocol SGViewDelegate <NSObject>
    -(void)buttonPressed:(UIButton*)button;
    @end

    @interface SGView : UIView {
    }

      -(id)circleOfButtons:(int)buttonCount buttonSize:(CGFloat)buttonSize circleRadius:(CGFloat)circleRadius;

    @property (assign) id<SGViewDelegate> delegate;

    @end

SGView.m

#import "SGView.h"

    @implementation SGView : UIView

    -(id)circleOfButtons:(int)buttonCount buttonSize:(CGFloat)buttonSize circleRadius:(CGFloat)circleRadius
    {
    UIView *multipleViews                   = [[UIView alloc]initWithFrame:[UIScreen mainScreen].bounds];

    CGPoint screenCentre;
    CGPoint buttonCentre;

    screenCentre.x                          = CGRectGetWidth  ([UIScreen mainScreen].bounds) / 2;
    screenCentre.y                          = CGRectGetHeight ([UIScreen mainScreen].bounds) / 2;

    for (int i = 1; i <= buttonCount; i++) {
        CGFloat radians                     = 2 * M_PI * i / buttonCount;
        CGFloat arcStartPoint               = - M_PI / 2; // first point clockwise after 12 o'clock
        buttonCentre.x                      = screenCentre.x + circleRadius * cos(radians + arcStartPoint);
        buttonCentre.y                      = screenCentre.y + circleRadius * sin(radians + arcStartPoint);

        CGPoint target                      = CGPointMake(buttonCentre.x, buttonCentre.y);
        CGFloat x                           = screenCentre.x - buttonSize / 2;
        CGFloat y                           = screenCentre.y - buttonSize / 2;
        CGFloat wide                        = buttonSize;
        CGFloat high                        = buttonSize;
        UIButton *circleButton              = [[UIButton alloc] initWithFrame:CGRectMake(x, y, wide, high)];

        [circleButton setTag:i];
        [circleButton addTarget:self.delegate action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];

        circleButton.clipsToBounds          = YES;
        circleButton.layer.masksToBounds    = NO;
        circleButton.layer.shadowOffset     = CGSizeMake(-15, 20);
        circleButton.layer.shadowRadius     = 5;
        circleButton.layer.shadowOpacity    = 0.0;
        circleButton.layer.borderWidth      = 0.25f;
        circleButton.layer.cornerRadius     = buttonSize/2;
        circleButton.layer.borderColor      = [UIColor blackColor].CGColor;
        circleButton.backgroundColor        = UIColor.whiteColor;
        [circleButton setTitle:[NSString stringWithFormat:@"%i", i] forState:UIControlStateNormal];

        if (buttonCount > 25) {
            [circleButton setTitleColor: [UIColor clearColor] forState:UIControlStateNormal];
            } else {
            [circleButton setTitleColor: [UIColor grayColor] forState:UIControlStateNormal];
        }

        [multipleViews addSubview:circleButton];

    // animation 1
        [UIView animateWithDuration:0.5 animations:^{
        circleButton.transform              = CGAffineTransformMakeScale(1.0, 1.0);
        circleButton.center                 = screenCentre;
        }
                     completion:^(BOOL finished){}];

    // animation 2
        [UIView animateWithDuration:0.5f animations:^{
        circleButton.transform              = CGAffineTransformIdentity;
        circleButton.center                 = target;
        }
                     completion:^(BOOL finished){}];
    }
    return multipleViews;
}
@end