C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了objective-c – 在保留自动布局约束的同时更换NSView大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我想在保留约束的同时将一个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所遇到的程序开发问题。

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。