成员引用基类型 '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
我正在尝试制作一个 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