objective-c – 在保留自动布局约束的同时更换NSView

objective-c – 在保留自动布局约束的同时更换NSView,第1张

概述我想在保留约束的同时将一个NSView替换为其他视图. 我有一个superview,subview,因为它是小孩和占位符,我打算迁移到子视图的地方. 但它似乎是代码 [[superview] replaceSubview:subview with:placeholder]; 删除与子视图相关的所有约束,并删除子视图. 约束如何从一个视图“复制”到另一个视图? 这是我写的很久以前的一些代码来做你所要 我想在保留约束的同时将一个NSVIEw替换为其他视图.

我有一个supervIEw,subvIEw,因为它是小孩和占位符,我打算迁移到子视图的地方.
但它似乎是代码

[[supervIEw] replaceSubvIEw:subvIEw with:placeholder];

删除与子视图相关的所有约束,并删除子视图.

约束如何从一个视图“复制”到另一个视图?

解决方法 这是我写的很久以前的一些代码来做你所要求的.

我的代码用于在同一个超级视图中交换两个NSVIEw,但是您可以轻松地将其替换为剥离不必要的位,并以仔细的顺序执行视图/约束添加和删除.事实上,我在“代理”视图控制器类中有一个较短的版本的代码,它完全符合你的要求,但我不能共享,因为它是一个不属于我的专有项目.

我会告诉你,你需要做的是将约束从代理视图复制到新视图,然后将新视图添加到超级视图.之后,将代理的超级视图约束复制到新视图,只有在您执行此 *** 作后,才能从超级视图中删除代理视图.

- (voID)swapVIEw:(NSVIEw*) source withVIEw:(NSVIEw*) dest persist:(BOol) persist{    NSLog(@"swapPing %@ with %@",source.IDentifIEr,dest.IDentifIEr);    // !!!: adjust the "auto Layout" constraints for the supervIEw.    // otherwise changing the frames is impossible. (instant reversion)    // we Could disable "auto Layout",but let's try for compatibility    // Todo: we need to either enforce that the 2 controls have the same supervIEw    // before accepting the drag operation    // or modify this code to take two diffrent supervIEws into account    // we are altering the constraints so iterate a copy!    NSArray* constraints = [dest.supervIEw.constraints copy];    for (NSLayoutConstraint* constraint in constraints) {        ID first = constraint.firstItem;        ID second = constraint.secondItem;        ID newFirst = first;        ID newSecond = second;        BOol match = NO;        if (first == dest) {            newFirst = source;            match = YES;        }        if (second == dest) {            newSecond = source;            match = YES;        }        if (first == source) {            newFirst = dest;            match = YES;        }        if (second == source) {            newSecond = dest;            match = YES;        }        if (match && newFirst) {            [dest.supervIEw removeConstraint:constraint];            @try {                NSLayoutConstraint* newConstraint = nil;                newConstraint = [NSLayoutConstraint constraintWithItem:newFirst                                                             attribute:constraint.firstAttribute                                                             relatedBy:constraint.relation                                                                toItem:newSecond                                                             attribute:constraint.secondAttribute                                                            multiplIEr:constraint.multiplIEr                                                              constant:constraint.constant];                newConstraint.shouldBeArchived = constraint.shouldBeArchived;                newConstraint.priority = NSLayoutPrioritywindowsizeStayPut;                [dest.supervIEw addConstraint:newConstraint];            }            @catch (NSException *exception) {                NSLog(@"Constraint exception: %@\nFor constraint: %@",exception,constraint);            }        }    }    [constraints release];    NSMutableArray* newSourceConstraints = [NSMutableArray array];    NSMutableArray* newDestConstraints = [NSMutableArray array];    // again we need a copy since we will be altering the original    constraints = [source.constraints copy];    for (NSLayoutConstraint* constraint in constraints) {        // WARNING: do not tamper with intrinsic layout constraints        if ([constraint class] == [NSLayoutConstraint class]            && constraint.firstItem == source) {            // this is a source constraint. we need to copy it to the destination.            NSLayoutConstraint* newConstraint = nil;            newConstraint = [NSLayoutConstraint constraintWithItem:dest                                                         attribute:constraint.firstAttribute                                                         relatedBy:constraint.relation                                                            toItem:constraint.secondItem                                                         attribute:constraint.secondAttribute                                                        multiplIEr:constraint.multiplIEr                                                          constant:constraint.constant];            newConstraint.shouldBeArchived = constraint.shouldBeArchived;            [newDestConstraints addobject:newConstraint];            [source removeConstraint:constraint];        }    }    [constraints release];    // again we need a copy since we will be altering the original    constraints = [dest.constraints copy];    for (NSLayoutConstraint* constraint in constraints) {        // WARNING: do not tamper with intrinsic layout constraints        if ([constraint class] == [NSLayoutConstraint class]            && constraint.firstItem == dest) {            // this is a destination constraint. we need to copy it to the source.            NSLayoutConstraint* newConstraint = nil;            newConstraint = [NSLayoutConstraint constraintWithItem:source                                                         attribute:constraint.firstAttribute                                                         relatedBy:constraint.relation                                                            toItem:constraint.secondItem                                                         attribute:constraint.secondAttribute                                                        multiplIEr:constraint.multiplIEr                                                          constant:constraint.constant];            newConstraint.shouldBeArchived = constraint.shouldBeArchived;            [newSourceConstraints addobject:newConstraint];            [dest removeConstraint:constraint];        }    }    [constraints release];    [dest addConstraints:newDestConstraints];    [source addConstraints:newSourceConstraints];    // auto layout makes setting the frame unnecissary,but    // we do it because its possible that a module is not using auto layout    NSRect srcRect = source.frame;    NSRect dstRect = dest.frame;    // round the coordinates!!!    // otherwise we will have problems with persistant values    srcRect.origin.x = round(srcRect.origin.x);    srcRect.origin.y = round(srcRect.origin.y);    dstRect.origin.x = round(dstRect.origin.x);    dstRect.origin.y = round(dstRect.origin.y);    source.frame = dstRect;    dest.frame = srcRect;    if (persist) {        Nsstring* rectString = NsstringFromrect(srcRect);        [[_theme prefrences] setobject:rectString forKey:dest.IDentifIEr];        rectString = NsstringFromrect(dstRect);        [[_theme prefrences] setobject:rectString forKey:source.IDentifIEr];    }}

你可以放心地忽略你想象的情况下的持久性.在我的情况下,我想实现iOS跳板功能(能够点按并按住一个按钮,它会跳动,让我拖动到另一个按钮,并在发射之间交换位置)

总结

以上是内存溢出为你收集整理的objective-c – 在保留自动布局约束的同时更换NSView全部内容,希望文章能够帮你解决objective-c – 在保留自动布局约束的同时更换NSView所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1251054.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-07
下一篇2022-06-07

发表评论

登录后才能评论

评论列表(0条)

    保存