成员引用基类型“类”不是结构或联合——Fixit 是不是将我引向了正确的方向?
Posted
技术标签:
【中文标题】成员引用基类型“类”不是结构或联合——Fixit 是不是将我引向了正确的方向?【英文标题】:Member reference base type 'Class' is not a structure or union - has the Fixit led me in the right direction?成员引用基类型“类”不是结构或联合——Fixit 是否将我引向了正确的方向? 【发布时间】:2017-03-31 23:53:36 【问题描述】:我正在尝试创建一个delegate
,它将在名为UIView
的自定义UIView
中发送来自UIButtons
的消息SGView
,并且在错误消息之后有点超出我的深度。我最近学会了如何获得delegate to send messages successfully from within an instance method。
SGView
包含一个类方法,将多个UIButtons
排列成一个圆圈,旨在供不同的UIViews.
The geometry works when the method is called from a parent UIView 使用。我现在通过在类方法声明中添加@protocol
和@property
来声明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报告了三个错误
'objc_class' 的定义必须从模块中导入 'ObjectiveC.runtime' 之前是必需的
“struct objc_class”中没有名为“delegate”的成员
成员引用类型'struct objc_class *'是一个指针;你的意思是 使用'->'?
Xcode 为最后一个提供了 Fixit
Fixit Replace”.” with “->”
通过接受 Fixit,我删除了三个问题并引入了另一个
成员引用基类型“类”不是结构或联合
如果这个 Fixit 引导我朝着正确的方向前进,那么接下来我应该做什么?
在回到Apple documentation 和these tutorials 试图解决它之前,我需要问这个问题以弄清这个看似直截了当的问题。非常感谢任何帮助。谢谢。
解决方案
这可以在我对自己问题的回答中找到。
【问题讨论】:
【参考方案1】:将类方法更改为实例方法似乎解决了我的问题。
这涉及将类方法 +(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
重复使用,这改变了UIButtons
的数量和大小排列成一个圆圈。 SGView
中的委托还允许每个按钮将标记消息发送到另一个类中的方法 - 在我的例子中是 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
【讨论】:
以上是关于成员引用基类型“类”不是结构或联合——Fixit 是不是将我引向了正确的方向?的主要内容,如果未能解决你的问题,请参考以下文章