ios - 将 CGAffineTransform Scale 应用于 UIView 使图层边框也变大

标签 ios objective-c uigesturerecognizer cgaffinetransformscale

我有一个 UIView,里面有一个 UIImageView。我在 UIVIew 中添加了一个 UIPinchGestureRecognizer 来处理捏合和缩放,并使 UIView 与 UIImageView 一起增长。

我的 UIView 有边框。我以这种方式添加了边框:

self.layer.borderColor = [UIColor blackColor].CGColor;
self.layer.borderWidth = 1.0f;
self.layer.cornerRadius = 8.0f;

我遇到的问题是我无法找到一种方法来使我的 UIView 变大,同时保持相同的边框宽度。捏合和缩放时,边框会变粗。

这是我的 UIPinchGestureRecognizer 处理程序:

- (void)scale:(UIPanGestureRecognizer *)sender{

    if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
        _lastScale = 1.0;
    }

    CGFloat scale = 1.0 - (_lastScale - [(UIPinchGestureRecognizer*)sender scale]);

    CGAffineTransform currentTransform = self.transform;
    CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);

    _lastScale = [(UIPinchGestureRecognizer*)sender scale];

    [self setTransform:newTransform];
}

非常感谢!!

我在谷歌上搜索了很多,发现了这个:

self.layer.borderWidth = 2.0f / scaleFactor;

可悲的是对我不起作用......它有道理但不起作用。

我还阅读了关于在后面添加另一个 View 并使前 View 在位置上有偏移的解决方案,以便显示后 View 并且看起来像边框。这不是一个选项,因为我需要我的图像才能查看透明。

我想重新创建 Aviary 在他们的应用程序中所做的事情。您可以放大和缩小“贴纸”,边框始终保持相同大小。

最佳答案

我也在 Swift 4.2 中尝试以这种方式实现这种效果。最终我无法使用 CGAffine Effects 成功地做到这一点。我最终不得不更新约束——因为我使用的是 anchor 。

这是我最终开始使用的代码。 SelectedView 是应该缩放的 View 。

请记住,这不会破坏其他 CGAffine 效果。我仍在使用它们进行轮换。

@objc private func scaleSelectedView(_ sender: UIPinchGestureRecognizer) {
    guard let selectedView = selectedView else {
        return
    }

    var heightDifference: CGFloat?
    var widthDifference: CGFloat?

    // increase width and height according to scale
    selectedView.constraints.forEach { constraint in
        guard
            let view = constraint.firstItem as? UIView,
            view == selectedView
            else {
                return
        }
        switch constraint.firstAttribute {
        case .width:
            let previousWidth = constraint.constant
            constraint.constant = constraint.constant * sender.scale
            widthDifference = constraint.constant - previousWidth
        case .height:
            let previousHeight = constraint.constant
            constraint.constant = constraint.constant * sender.scale
            heightDifference = constraint.constant - previousHeight
        default:
            return
        }
    }

    // adjust leading and top anchors to keep view centered
    selectedView.superview?.constraints.forEach { constraint in
        guard
            let view = constraint.firstItem as? UIView,
            view == selectedView
            else {
                return
        }
        switch constraint.firstAttribute {
        case .leading:
            guard let widthDifference = widthDifference else {
                return
            }
            constraint.constant = constraint.constant - widthDifference / 2
        case .top:
            guard let heightDifference = heightDifference else {
                return
            }
            constraint.constant = constraint.constant - heightDifference / 2
        default:
            return
        }
    }

    // reset scale after applying in order to keep scaling linear rather than exponential
    sender.scale = 1.0
}

注意:宽度和高度 anchor 位于 View 本身。 Top 和 Leading anchor 在 super View 上——因此有两个 forEach block 。

关于ios - 将 CGAffineTransform Scale 应用于 UIView 使图层边框也变大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24682706/

相关文章:

ios - Appcelerator - 获取地理位置信息并转化为 URL

objective-c - 如何将下面 Objective-C 中的 JSON 转换为 Swift?

iphone - 使用 UISwipeGestureRecognizer 滑动 View

swift - Pan 手势和 Tap 手势之间的冲突

ios - 在已经使用 SQLite 的现有应用程序中采用核心数据

ios - 如何使用 PhotoKit 访问慢动作视频的 NSData/NSURL

objective-c - 获取 NSButton 上的悬停事件以显示图像

objective-c - 如何在 Xcode 中添加 Watch 或 Inspect?

iOS自定义手势识别器测量长按的长度

ios - 为什么当应用程序在后台时,带有enableBackgroundDeliveryForType的HKAnchoredObjectQuery不总是触发?