继承 UIView - 丢失实例变量

发布于 2024-10-08 09:46:33 字数 2945 浏览 0 评论 0原文

作为一名 Objective-C 新手,我四处寻找答案,但一直找不到答案,所以如果这是一个显而易见的问题,请原谅我。

基本上,我需要在屏幕上绘制圆的分段(例如,90 度分段,水平线和垂直线在左下角相交,圆弧连接端点)。我成功地在一个名为 CircleSegment 的自定义类中实现了这一点,该类继承 UIView 并覆盖 drawRect

我的问题是以编程方式实现这一点;我需要某种方法来创建 CircleSegment 类,并在绘制线段本身之前在其中存储所需的角度。

这是我到目前为止所拥有的:

CircleSegment.h

#import <UIKit/UIKit.h>

@interface CircleSegment : UIView {
    float angleSize;
    UIColor *backColor;
}

-(float)convertDegToRad:(float)degrees;
-(float)convertRadToDeg:(float)radians;

@property (nonatomic) float angleSize;
@property (nonatomic, retain) UIColor *backColor;

@end

CircleSegment.m

#import "CircleSegment.h"


@implementation CircleSegment

@synthesize angleSize;
@synthesize backColor;


// INITIALISATION OVERRIDES
// ------------------------

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        self.opaque = NO;
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

- (void)setBackgroundColor:(UIColor *)newBGColor
{
    // Ignore.
}
- (void)setOpaque:(BOOL)newIsOpaque
{
    // Ignore.
}



// MATH FUNCTIONS
// --------------

// Converts degrees to radians.
-(float)convertDegToRad:(float)degrees {
    return degrees * M_PI / 180;    
}

// Converts radians to degrees.
-(float)convertRadToDeg:(float)radians {
    return radians * 180 / M_PI;
}


// DRAWING CODE
// ------------

- (void)drawRect:(CGRect)rect {

    float endAngle = 360 - angleSize;

    UIBezierPath* aPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100)
                                                         radius:100
                                                     startAngle:[self convertDegToRad:270]
                                                       endAngle:[self convertDegToRad:endAngle]
                                                      clockwise:YES];

    [aPath addLineToPoint:CGPointMake(100.0, 100.0)];

    [aPath closePath];

    CGContextRef aRef = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(aRef, backColor.CGColor);

    CGContextSaveGState(aRef);

    aPath.lineWidth = 1;

    [aPath fill];
    [aPath stroke];

    //CGContextRestoreGState(aRef);


}

- (void)dealloc {
    [super dealloc];
}


@end

请注意,.m 文件有点混乱,其中包含各种测试代码......

所以本质上我想要要创建 CircleSegment 的实例,请在 angleSize 属性中存储一个角度,根据该角度绘制一个线段,然后将该视图添加到主应用程序视图中以显示它...

为了尝试实现这一目标,我添加了以下内容在我的 ViewController 上测试 viewDidLoad 代码:

CircleSegment *seg1 = [[CircleSegment alloc] init];
seg1.backColor = [UIColor greenColor];
seg1.angleSize = 10;

[self.view addSubview:seg1];

当我在这些地方断点时,它似乎可以很好地存储 UIColor 和 angleSize,但是如果我在 drawRect 中放置一个断点,我会在 CircleSegment 上覆盖它.m,这些值已恢复为零值(或者无论正确的术语是什么,请随时纠正我)。

如果有人能指出我正确的方向,我将非常感激!

谢谢

Bit of an Objective-C rookie, I've looked around for an answer but haven't been able to find one so forgive me if this is an obvious question.

Basically, I need to draw on the screen segments of a circle (for instance, a 90 degree segment, where a horizontal and vertical line meet at the bottom left and an arc connects the end points). I've managed to achieve this in a custom class called CircleSegment that inherits UIView and overrides drawRect.

My issue is achieving this programatically; I need some way of creating my CircleSegment class and storing in it the desired angle before it draws the segment itself.

Here's what I have so far:

CircleSegment.h

#import <UIKit/UIKit.h>

@interface CircleSegment : UIView {
    float angleSize;
    UIColor *backColor;
}

-(float)convertDegToRad:(float)degrees;
-(float)convertRadToDeg:(float)radians;

@property (nonatomic) float angleSize;
@property (nonatomic, retain) UIColor *backColor;

@end

CircleSegment.m

#import "CircleSegment.h"


@implementation CircleSegment

@synthesize angleSize;
@synthesize backColor;


// INITIALISATION OVERRIDES
// ------------------------

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        self.opaque = NO;
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

- (void)setBackgroundColor:(UIColor *)newBGColor
{
    // Ignore.
}
- (void)setOpaque:(BOOL)newIsOpaque
{
    // Ignore.
}



// MATH FUNCTIONS
// --------------

// Converts degrees to radians.
-(float)convertDegToRad:(float)degrees {
    return degrees * M_PI / 180;    
}

// Converts radians to degrees.
-(float)convertRadToDeg:(float)radians {
    return radians * 180 / M_PI;
}


// DRAWING CODE
// ------------

- (void)drawRect:(CGRect)rect {

    float endAngle = 360 - angleSize;

    UIBezierPath* aPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(100, 100)
                                                         radius:100
                                                     startAngle:[self convertDegToRad:270]
                                                       endAngle:[self convertDegToRad:endAngle]
                                                      clockwise:YES];

    [aPath addLineToPoint:CGPointMake(100.0, 100.0)];

    [aPath closePath];

    CGContextRef aRef = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(aRef, backColor.CGColor);

    CGContextSaveGState(aRef);

    aPath.lineWidth = 1;

    [aPath fill];
    [aPath stroke];

    //CGContextRestoreGState(aRef);


}

- (void)dealloc {
    [super dealloc];
}


@end

Note that the .m file is a bit messy with various bits of test code...

So essentially I want to create an instance of CircleSegment, store an angle in the angleSize property, draw a segment based on that angle and then add that view to the main app view to display it...

To try and achieve that, I've add the following test code to viewDidLoad on my ViewController:

CircleSegment *seg1 = [[CircleSegment alloc] init];
seg1.backColor = [UIColor greenColor];
seg1.angleSize = 10;

[self.view addSubview:seg1];

It seems to store the UIColor and angleSize fine when I breakpoint those places, however if I place a breakpoint in drawRect which I overrode on CircleSegment.m, the values have reverted back to nil values (or whatever the correct term would be, feel free to correct me).

I'd really appreciate it if someone could point me in the right direction!

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

南薇 2024-10-15 09:46:33

它似乎存储了 UIColor 和
当我断点这些时,angleSize 很好
地方,但是如果我放置一个
我在drawRect中的断点
覆盖了 CircleSegment.m,
值已恢复为零
值(或任何正确的术语
是的,请随时纠正我)。

您确定正在使用同一个实例吗?

viewDidLoaddrawRect 中添加类似 NSLog(@"%@ %p", NSStringFromSelector(_cmd), self); 的内容,然后进行制作确保您实际上正在处理同一个实例。

(我见过开发人员alloc/initWithFrame:一个视图,然后使用在NIB加载期间创建的实例,想知道为什么该实例不正确已初始化。)

It seems to store the UIColor and
angleSize fine when I breakpoint those
places, however if I place a
breakpoint in drawRect which I
overrode on CircleSegment.m, the
values have reverted back to nil
values (or whatever the correct term
would be, feel free to correct me).

Are you sure you are working with the same instance?

Drop in something like NSLog(@"%@ %p", NSStringFromSelector(_cmd), self); in viewDidLoad and in drawRect and make sure you are actually dealing with the same instance.

(I've seen cases where a developer will alloc/initWithFrame: a view and then use the instance that was created during NIB loading, wondering why that instance wasn't properly initialized.)

堇色安年 2024-10-15 09:46:33

尝试在 DrawRect 方法中使用 self.angleSize (与 backColor 相同)。在您的测试方法中,将 10 替换为 10.0(以确保将其设置为浮点数)。

另外,不要忘记在 dealloc 中释放 backColor。

Try using self.angleSize in your DrawRect method (same with backColor). In your test method, replace 10 with 10.0 (to ensure it's setting it as a float).

Also, don't forget to release backColor in your dealloc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文