Objective c 更改CGRect(或任何结构)?
我在代码中经常这样做:Objective c 更改CGRect(或任何结构)?,objective-c,data-structures,Objective C,Data Structures,我在代码中经常这样做: self.sliderOne.frame = CGRectMake(newX, 0, self.sliderOne.frame.size.width, self.sliderOne.frame.size.height); 有什么方法可以避免这个繁琐的代码吗?我试过这种类型的东西: self.sliderOne.frame.origin.x = newX; 但是我得到了赋值的左操作数所需的左值错误。这里的问题是self.slideron.frame.origin.x
self.sliderOne.frame = CGRectMake(newX, 0, self.sliderOne.frame.size.width, self.sliderOne.frame.size.height);
有什么方法可以避免这个繁琐的代码吗?我试过这种类型的东西:
self.sliderOne.frame.origin.x = newX;
但是我得到了赋值的左操作数所需的
左值
错误。这里的问题是self.slideron.frame.origin.x
与[[self sliderOne]frame.origin.x
相同。正如您所看到的,在这里分配回左值并不是您想要做的事情
所以不,虽然可以缩短一点,但“冗长”的代码是必要的
CGRect rect = thing.frame;
thing.frame = CGRectMake(CGRectGetMinX(rect), CGRectGetMinY(rect) + 10, etc...);
是的,你必须做到:
CGRect newFrame = self.sliderOne.frame;
newFrame.origin.x = frame.size.width - MARGIN * 2 - totalWidth;
self.sliderOne.frame = newFrame;
我知道这很糟糕。如果您发现自己经常这样做,您可能需要将类别添加到UIView/NSView,以便为您更改这些内容:
@interface UIView (FrameMucking)
- (void) setWidth:(CGFloat)newWidth;
@end
@implementation UIView (FrameMucking)
- (void) setWidth:(CGFloat)newWidth {
CGRect f = [self frame];
f.size.width = newWidth;
[self setFrame:f];
}
@end
等等。我终于按照@Dave DeLong的建议做了一个分类。您所要做的就是在任何想要利用它的类中导入它 UIView+AlterFrame.h
#import <UIKit/UIKit.h>
@interface UIView (AlterFrame)
- (void) setFrameWidth:(CGFloat)newWidth;
- (void) setFrameHeight:(CGFloat)newHeight;
- (void) setFrameOriginX:(CGFloat)newX;
- (void) setFrameOriginY:(CGFloat)newY;
@end
我可以用积木把方法弄干。。。我希望我很快就会这么做
稍后:我刚刚注意到
CGRectOffset
和CGRectInset
,所以这个类别可以稍微清理一下(如果不完全删除的话)。。我不知道类别是猴子修补的objective-c(或c?)机制。非常有趣。@yar它们是一种机制,也是我最喜欢的Objective-C语言功能之一。:)哇,我刚刚注意到你说你可以使用f.size.width=
设置宽度。。。我希望这是真的。@Danielf
是一个C结构,这意味着f.size.width=42
将更改本地存储的变量。然后,您必须通过setFrame:
将这些更改应用到UIView中,它需要一个结构作为参数。我已经做了几十次了。@Dave DeLong:我不明白为什么我可以更改f.size.width,而不能更改self.frame.size.width。。。这是问题的核心。它是否因为使用了变量而变短?我想,我遗漏了一些东西。对于你不拥有的框架的分类方法总是很好的,用一个唯一的前缀标记这些方法。在Google Toolbox for Mac中,我们使用gtm,所以这将是gtm setFrameWidth:等等。这样,如果苹果将来决定定义setFrameWidth:它与您的类别没有冲突。谢谢@dmaclach,与Java相比,这一切看起来太原始了,Java当然不允许您修改框架类:)我会接受您的建议。@dmaclach,我必须说,虽然我确实为这个问题找到了一个最好的答案,但我仍然不明白为什么不能只做“self.frame.size.width=30;”。。。简而言之,点符号用于属性访问和结构成员。这里有龙。。。对于obj=nil,[obj doThis]最终发送消息nil,这很好。对于点表示法的情况,如果我读对了,你要么有效地赋值给一个左值nil(bzzzt!),要么试图调用‘nil’,而不使用Objective-C的括号表示法(也是bzzzt!)。“doThis”中的“do”告诉我,“doThis”更多的是一种行为,而不是一种状态的表示。因此,在这种情况下应该使用括号表示法。仅使用点表示法来获取和设置对象状态(事实证明,如果您愿意,这也会产生一些好的副作用)。看克里斯·汉森的文章——他解释得很好!
#import "UIView+AlterFrame.h"
@implementation UIView (AlterFrame)
- (void) setFrameWidth:(CGFloat)newWidth {
CGRect f = self.frame;
f.size.width = newWidth;
self.frame = f;
}
- (void) setFrameHeight:(CGFloat)newHeight {
CGRect f = self.frame;
f.size.height = newHeight;
self.frame = f;
}
- (void) setFrameOriginX:(CGFloat)newX {
CGRect f = self.frame;
f.origin.x = newX;
self.frame = f;
}
- (void) setFrameOriginY:(CGFloat)newY {
CGRect f = self.frame;
f.origin.y = newY;
self.frame = f;
}
@end