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=
设置宽度。。。我希望这是真的。@Daniel
f
是一个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