iOS框架改变一个属性(例如宽度)

Jac*_*nkr 41 objective-c ios cgrect cgrectmake

这个问题最初是针对objective-c编程语言提出的.在撰写本文时,swift甚至还没有存在.

是否有可能只更改一个属性CGRect

例如:

self.frame.size.width = 50;
Run Code Online (Sandbox Code Playgroud)

代替

self.frame = CGRectMake(self.frame.origin.x, 
                        self.frame.origin.y, 
                        self.frame.size.width, 
                        50);
Run Code Online (Sandbox Code Playgroud)

当然我明白这self.frame.size.width只读的所以我想知道如何做到这一点?

CSS ANALOGY 风险自负

对于那些熟悉的人来说CSS,这个想法非常类似于使用:

margin-left: 2px;
Run Code Online (Sandbox Code Playgroud)

而不是必须改变整个价值:

margin: 5px 5px 5px 2px;
Run Code Online (Sandbox Code Playgroud)

Ole*_*ann 98

回答你原来的问题:是的,可以改变一个CGRect结构的一个成员.此代码不会抛出任何错误:

myRect.size.width = 50;
Run Code Online (Sandbox Code Playgroud)

什么是没有可能的,但是,是改变的一个成员CGRect,其本身的另一个对象的属性.在这种非常常见的情况下,您必须使用临时局部变量:

CGRect frameRect = self.frame;
frameRect.size.width = 50;
self.frame = frameRect;
Run Code Online (Sandbox Code Playgroud)

这样做的原因是使用属性访问self.frame = ...器等同[self setFrame:...]于此访问器总是需要一个整体CGRect.struct在这种情况下,将C样式访问与Objective-C属性点表示法混合使用效果不佳.

  • 要提一下这个 - "self.frame.size.width = 50"在Swift中有效. (8认同)
  • 正如我所说的,它通常可以工作,但如果`CGRect`是Objective-C对象的属性,它确实_not_,如在你的例子中.米洛斯可能是指您的示例代码,在这方面是正确的. (2认同)

Art*_*are 28

我喜欢Ahmed Khalaf的回答,但我想到你也可以写出一些C函数......关键优势在于你在使用错误的情况下更容易找到错误类型.

话虽如此,我用这些函数声明写了一个.h文件:

CGRect CGRectSetWidth(CGRect rect, CGFloat width);
CGRect CGRectSetHeight(CGRect rect, CGFloat height);
CGRect CGRectSetSize(CGRect rect, CGSize size);
CGRect CGRectSetX(CGRect rect, CGFloat x);
CGRect CGRectSetY(CGRect rect, CGFloat y);
CGRect CGRectSetOrigin(CGRect rect, CGPoint origin);
Run Code Online (Sandbox Code Playgroud)

以及具有这些函数实现的相应.m文件:

CGRect CGRectSetWidth(CGRect rect, CGFloat width) {
    return CGRectMake(rect.origin.x, rect.origin.y, width, rect.size.height);
}

CGRect CGRectSetHeight(CGRect rect, CGFloat height) {
    return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, height);
}

CGRect CGRectSetSize(CGRect rect, CGSize size) {
    return CGRectMake(rect.origin.x, rect.origin.y, size.width, size.height);
}

CGRect CGRectSetX(CGRect rect, CGFloat x) {
    return CGRectMake(x, rect.origin.y, rect.size.width, rect.size.height);
}

CGRect CGRectSetY(CGRect rect, CGFloat y) {
    return CGRectMake(rect.origin.x, y, rect.size.width, rect.size.height);
}

CGRect CGRectSetOrigin(CGRect rect, CGPoint origin) {
    return CGRectMake(origin.x, origin.y, rect.size.width, rect.size.height);
}
Run Code Online (Sandbox Code Playgroud)

所以,现在,要做你想做的事,你可以这样做:

self.frame = CGRectSetWidth(self.frame, 50);
Run Code Online (Sandbox Code Playgroud)

得到Fancier(一年后更新我做的)

不过,这有一个多余self.frame的内容.要解决这个问题,您可以使用如下所示的方法添加categoryon UIView:

- (void) setFrameWidth:(CGFloat)width {
    self.frame = CGRectSetWidth(self.frame, width); // You could also use a full CGRectMake() function here, if you'd rather.
}
Run Code Online (Sandbox Code Playgroud)

现在你可以输入:

[self setFrameWidth:50];
Run Code Online (Sandbox Code Playgroud)

或者,甚至更好:

self.frameWidth = 50;
Run Code Online (Sandbox Code Playgroud)

这样你就可以做到这样的事情:

self.frameWidth = otherView.frameWidth; // as opposed to self.frameWidth = otherView.frame.size.width;
Run Code Online (Sandbox Code Playgroud)

你需要在你的类别中有这个:

- (CGFloat) frameWidth {
    return self.frame.size.width;
}
Run Code Online (Sandbox Code Playgroud)

请享用.

  • @CarlosP编号`const int MY_SUBCLASS_LEFT_MARGIN = 10;` - 你应该使用#define的唯一时间是只能在编译时知道的东西,例如,有关编译器或正在编译的版本的详细信息可能是定义的.假设你正在开展一个大型项目,而其他地方的人则有#define MARGIN 8.现在您的定义被破坏,构建失败.添加`const`是有原因的,我需要把它归结为这么多的C,C++和Obj-C程序员,因为他们决心滥用CPP的`#define`. (2认同)

n0_*_*ter 6

基于ArtOfWarfare的解决方案(非常棒),我构建了UIView没有C函数的类别.

用法示例:

[self setFrameWidth:50];
self.frameWidth = 50;
self.frameWidth += 50;
self.frameWidth = otherView.frameWidth; // as opposed to self.frameWidth = otherView.frame.size.width;
Run Code Online (Sandbox Code Playgroud)

头文件UIView+easy_frame.h:

@interface UIView (easy_frame)

- (void) setFrameWidth:(CGFloat)width;
- (void) setFrameHeight:(CGFloat)height;
- (void) setFrameX:(CGFloat)x;
- (void) setFrameY:(CGFloat)y;

- (CGFloat) frameWidth;
- (CGFloat) frameHeight;
- (CGFloat) frameX;
- (CGFloat) frameY;
Run Code Online (Sandbox Code Playgroud)

实施文件UIView+easy_frame.m:

#import "UIView+easy_frame.h"
@implementation UIView (easy_frame)

# pragma mark - Setters

- (void) setFrameWidth:(CGFloat)width
{
  self.frame = CGRectMake(self.frame.origin.x,
                          self.frame.origin.y,
                          width,
                          self.frame.size.height);
}

- (void) setFrameHeight:(CGFloat)height
{
  self.frame = CGRectMake(self.frame.origin.x,
                          self.frame.origin.y,
                          self.frame.size.width,
                          height);
}

- (void) setFrameX:(CGFloat)x
{
  self.frame = CGRectMake(x,
                          self.frame.origin.y,
                          self.frame.size.width,
                          self.frame.size.height);
}

- (void) setFrameY:(CGFloat)y
{
  self.frame = CGRectMake(self.frame.origin.x,
                          y,
                          self.frame.size.width,
                          self.frame.size.height);
}

# pragma mark - Getters

- (CGFloat) frameWidth
{
  return self.frame.size.width;
}

- (CGFloat) frameHeight
{
  return self.frame.size.height;
}

- (CGFloat) frameX
{
  return self.frame.origin.x;
}

- (CGFloat) frameY
{
  return self.frame.origin.y;
}
Run Code Online (Sandbox Code Playgroud)