代码之家  ›  专栏  ›  技术社区  ›  Allisone

myview.frame.origin.x=value;不起作用-但为什么?

  •  31
  • Allisone  · 技术社区  · 14 年前

    我知道我不能用这个:

    myView.frame.origin.x = 25.0;
    

    我必须用这个来代替:

    CGRect myFrame = myView.frame;
    myFrame.origin.x = 25.0;
    myView.frame = myFrame;
    

    我一直在这样做,但我不知道为什么我必须这样做。我想填补我理解上的空白。有人能解释吗?

    现在xcode给了你“表达式不可赋值”。一段时间前,出现了一个编译错误“lvalue required as left operand of assignment”。

    4 回复  |  直到 12 年前
        1
  •  40
  •   walkytalky    14 年前

    这里使用了两种不同的点语法。它们看起来是一样的,但是它们做不同的事情,这取决于它们在做什么和在做什么:

    • 第一 myView.frame [myView frame] ,返回 CGRect 结构 按价值 .
    • myFrame.origin.x 以传统的C方式访问普通结构成员。
    • 第二 MyVIEW框架 又是一个速记,但因为语句是 分配 它转换为调用不同的方法, [myView setFrame:myFrame] .

    在您的单行顶部示例中,您得到一个rect的副本并设置它 x ,但不要将其复制回视图。你必须明确区分方法调用,点语法糖不能将它们变为单个调用。

        2
  •  17
  •   Allisone    12 年前

    这不起作用的原因是两种语法的混合。
    首先,您可以使用“.”作为调用访问器函数(Objective-C特性)的快捷方式。 所以

    • A.B变为[A GETB];
    • A.B=5变为[A集合B:5];

    然后有“.”作为直接结构成员访问(纯C)。所以

    • A.B真的是A.B;
    • A.B真的是A.B=5;

    在这样一个设定值的情况下组合它是行不通的。
    因为… 如果你能打电话

    myView.frame.origin.x = 25.0;
    
    • “myview.frame”部分等于[myview get frame],您将得到一个复制的cgrect frame(C结构)

    • “myview.frame.origin”为您提供复制的cgrct的cgpoint origin(也是结构)。

    • “myview.frame.origin.x=25.0”给出了原点的cgfloat x,现在你想给它赋值,问题就出现了……

    您试图设置一个结构的结构变量,这是可以的,但没有从uiview指向该结构的指针,因此它被复制。所以你复制,然后设置,然后你期望设置操作通过最初的GET以某种方式转发到uiview,但是这不起作用。

    当然,你可能会想,为什么苹果公司没有创建一个快捷方式,这样最终你复制的帧会自动地重新注入到一个自动附加的setframe调用中,我猜你只需要按照它的方式生活。

    所以记住,如果你得到一个指向框架的指针,它会工作,但是你没有,你会得到一个复制的结构。
    所以如果你想的话 myView.frame.origin.x = 25.0 为了工作,你间接地期望你的呼叫被自动转换成
    [myView setFrame:[myView getFrame:frame].origin.x = 25.0] .
    我想你可以承认这看起来不对。

    同样想象一下,如果你得到一个指向CGRECT框架的直接指针,并且你通过这个指针改变了一些东西,那么uiview怎么知道它的大小已经改变了,它必须自己更新呢?另一方面,如果进行了一个[MyView setFrame:NewFrame]调用,那么uiView可以自行进行所有必要的重新调整。

        3
  •  2
  •   Emil    14 年前

    CGRect 是一个结构,它来自标准C.A CGRACT 一个目标C对象,因此当您分配给它的一个成员时,不会调用setter方法。如果不调用setter方法,uikit将无法知道任何更改,因此无法更新屏幕显示。

    编辑:正如已经指出的,分配将是结构的一个副本。

        4
  •  1
  •   Andy Obusek    12 年前

    当您直接操作数据时,不会调用访问器,因此UI不能更新自身,也不能通知任何其他想要了解更改的组件。

    编辑:正如Walkytalky所指出的,您将得到数据的副本,因此更改它对原始数据没有任何影响。下面的示例将显示这一点:

    UIView *aView = [[UIView alloc] initWithFrame:CGRectMake(50,50,100,100)];
    NSLog(@"%f", aView.frame.origin.x); // will give 50
    aView.frame.origin.x = 17;  // operates on a copy of the rect only
    NSLog(@"%f", aView.frame.origin.x);  // will still give 50