【问题标题】:how Add mirror image to 2d Box corners如何将镜像添加到 2d Box 角
【发布时间】:2019-09-04 10:45:06
【问题描述】:

你好朋友我需要在右上角和底部添加镜像。 我在这个答案的帮助下创建了视图类型

how to create a view like this shape in swift?

但我无法在右上角和底部

添加图片

【问题讨论】:

    标签: ios swift core-graphics core-animation swift5


    【解决方案1】:

    当前的方法与previous 的方法有些不同。

    之前我已经绘制了右上角和下角并调整了图像的大小,以便在question 中询问外观。

    但在这个问题中,这种方法将不再适用。第一个原因是draw(in rect: CGRect) 在绘图时不提供镜像功能。 iOS 仅在绘制UIImageView 时提供镜像功能。所以要进行镜像,我们需要设置 3 个图像视图。

    所以实现它的方法如下

    1. 在中间放一个UIImageView
    2. 将一个UIImageView 放在中间的右侧,另一个放在底部。
    3. 现在计算右镜像并应用剪切右图像视图。
    4. 对底部做同样的事情。

    上述方法中仍然存在一个问题。例如我们根据 y 轴剪切右图像视图。剪切操作与中心一起工作。所以左侧和右侧都在 y 轴上剪切。所以我们将正向平移到 x 轴,以便所有剪切都适用于UIImageView 的右侧。 这就是为什么要重叠右侧和主图像视图以填补 to 之间的空白,如下所示

    rightImageView.leadingAnchor.constraint(equalTo: mainImageView.trailingAnchor, constant: -stripSize / 2),
    

    底部图像视图也是如此。

    代码

    lass ViewController: UIViewController {
    
        let mainImageView: UIImageView = {
            let view = UIImageView()
            view.translatesAutoresizingMaskIntoConstraints = false
            view.clipsToBounds = true
            return view
        }()
        let rightImageView: UIImageView = {
            let view = UIImageView()
            view.translatesAutoresizingMaskIntoConstraints = false
            view.clipsToBounds = true
            return view
        }()
        let bottomImageView: UIImageView = {
            let view = UIImageView()
            view.translatesAutoresizingMaskIntoConstraints = false
            view.clipsToBounds = true
            return view
        }()
    
        let rightDarkView: UIView = {
            let view = UIView()
            view.translatesAutoresizingMaskIntoConstraints = false
            view.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.4)
            return view
        }()
    
        let bottomDarkView: UIView = {
            let view = UIView()
            view.translatesAutoresizingMaskIntoConstraints = false
            view.backgroundColor = UIColor.init(red: 0, green: 0, blue: 0, alpha: 0.5)
            return view
        }()
    
    
        let mainImageSize = CGSize(width: 240, height: 240)
        let stripSize = CGFloat(20)
    
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
    
            setupView()
            setupMirroView()
        }
    
    
    
        func setupView() {
            view.addSubview(mainImageView)
            view.addSubview(rightImageView)
            view.addSubview(bottomImageView)
    
            view.addSubview(rightDarkView)
            view.addSubview(bottomDarkView)
    
            NSLayoutConstraint.activate([
                mainImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                mainImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
                mainImageView.widthAnchor.constraint(equalToConstant: mainImageSize.width),
                mainImageView.heightAnchor.constraint(equalToConstant: mainImageSize.height),
    
                rightImageView.leadingAnchor.constraint(equalTo: mainImageView.trailingAnchor, constant: -stripSize / 2),
                rightImageView.topAnchor.constraint(equalTo: mainImageView.topAnchor),
                rightImageView.bottomAnchor.constraint(equalTo: mainImageView.bottomAnchor),
                rightImageView.widthAnchor.constraint(equalToConstant: stripSize),
    
                rightDarkView.leadingAnchor.constraint(equalTo: rightImageView.leadingAnchor),
                rightDarkView.topAnchor.constraint(equalTo: rightImageView.topAnchor),
                rightDarkView.trailingAnchor.constraint(equalTo: rightImageView.trailingAnchor),
                rightDarkView.bottomAnchor.constraint(equalTo: rightImageView.bottomAnchor),
    
                bottomImageView.topAnchor.constraint(equalTo: mainImageView.bottomAnchor, constant: -stripSize / 2),
                bottomImageView.leadingAnchor.constraint(equalTo: mainImageView.leadingAnchor),
                bottomImageView.trailingAnchor.constraint(equalTo: mainImageView.trailingAnchor),
                bottomImageView.heightAnchor.constraint(equalToConstant: stripSize),
    
                bottomDarkView.leadingAnchor.constraint(equalTo: bottomImageView.leadingAnchor),
                bottomDarkView.topAnchor.constraint(equalTo: bottomImageView.topAnchor),
                bottomDarkView.trailingAnchor.constraint(equalTo: bottomImageView.trailingAnchor),
                bottomDarkView.bottomAnchor.constraint(equalTo: bottomImageView.bottomAnchor)
    
                ])
        }
    
        func setupMirroView() {
            let image = UIImage(named: "image")
            mainImageView.image = image
    
            // prepare the image for the right image view
            let rightImage = image?.cropped(to: CGSize(width: stripSize, height: mainImageSize.height),
                                            drawInto: CGRect(x: stripSize - mainImageSize.width, y: 0, width: mainImageSize.width, height: mainImageSize.height))
            let rightImageMirrored = UIImage(cgImage: rightImage!.cgImage!, scale: 1.0, orientation: .upMirrored)
            rightImageView.image = rightImageMirrored
    
            var rightTransform = CGAffineTransform.identity
            rightTransform = rightTransform.translatedBy(x: stripSize / 2, y: 0)
            rightTransform = rightTransform.concatenating(CGAffineTransform(a: 1.0, b: 1.0, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0))
            rightImageView.transform = rightTransform
            rightDarkView.transform = rightTransform
    
    
            // prepare the image for the left image view
            let downImage = image?.cropped(to: CGSize(width: mainImageSize.width, height: stripSize),
                                           drawInto: CGRect(x: 0, y: stripSize - mainImageSize.height, width: mainImageSize.width, height: mainImageSize.height))
            let downImageMirroed = UIImage(cgImage: downImage!.cgImage!, scale: 1.0, orientation: .downMirrored)
            bottomImageView.image = downImageMirroed
    
            var downTransform = CGAffineTransform.identity
            downTransform = downTransform.translatedBy(x: 0, y: stripSize / 2)
            downTransform = downTransform.concatenating(__CGAffineTransformMake(1.0, 0.0, 1.0, 1.0, 0.0, 0.0))
            bottomImageView.transform = downTransform
            bottomDarkView.transform = downTransform
    
        }
    
    }
    
    extension UIImage {
        func cropped(to size: CGSize, drawInto: CGRect) -> UIImage {
            UIGraphicsBeginImageContext(size)
            self.draw(in: drawInto)
            let newImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return newImage!
        }
    }
    

    输出

    【讨论】:

      【解决方案2】:

      一种方法是使用 3 个图像视图 - “主” imageView 加上右侧的 imageView 和底部的 imageView。

      • 缩放您的图像以适合主视图 + 右侧和底部的少量。
      • 设置主imageView的.contentMode = .topLeft裁剪右下角。
      • 将右侧的imageView设置为.topRight以裁剪左右。
      • 将底部的imageView设置为.leftBottom以裁剪顶部和右侧。
      • 将右侧视图和底部视图的图像变暗(使其看起来有点“阴影”

      然后,将CGAffineTransform 应用于倾斜右侧和底部视图。

      使用此图片(3:2 比例)​​:

      还有这段代码(一切都通过代码完成 - 不需要 IBOutlets):

      import UIKit
      import CoreImage
      
      class ImageWorkViewController: UIViewController {
      
          let mainImageView: UIImageView = {
              let v = UIImageView()
              v.translatesAutoresizingMaskIntoConstraints = false
              v.clipsToBounds = true
              v.contentMode = .topLeft
              return v
          }()
      
          let rightImageView: UIImageView = {
              let v = UIImageView()
              v.translatesAutoresizingMaskIntoConstraints = false
              v.clipsToBounds = true
              v.contentMode = .topRight
              return v
          }()
      
          let bottomImageView: UIImageView = {
              let v = UIImageView()
              v.translatesAutoresizingMaskIntoConstraints = false
              v.clipsToBounds = true
              v.contentMode = .bottomLeft
              return v
          }()
      
          // this will be the width of the skewed right-side and height of the skewed bottom
          let vDepth:CGFloat = 10.0
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              view.addSubview(mainImageView)
              view.addSubview(rightImageView)
              view.addSubview(bottomImageView)
      
              NSLayoutConstraint.activate([
      
                  // constrain main image view 40-pts from each side
                  mainImageView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 40.0),
                  mainImageView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -40.0),
      
                  // centered vertically
                  mainImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0.0),
      
                  // use 3:2 ratio
                  mainImageView.heightAnchor.constraint(equalTo: mainImageView.widthAnchor, multiplier: 2.0 / 3.0),
      
                  // constrain right image view to main image view
                  //      right-edge
                  //      top + 1/2 of vDepth
                  //      equal height
                  //      width = vDepth
                  rightImageView.leadingAnchor.constraint(equalTo: mainImageView.trailingAnchor, constant: 0.0),
                  rightImageView.topAnchor.constraint(equalTo: mainImageView.topAnchor, constant: vDepth / 2.0),
                  rightImageView.heightAnchor.constraint(equalTo: mainImageView.heightAnchor, multiplier: 1.0),
                  rightImageView.widthAnchor.constraint(equalToConstant: vDepth),
      
                  // constrain bottom image view to main image view
                  //      left-edge + 1/2 of vDepth
                  //      bottom
                  //      equal width
                  //      height = vDepth
                  bottomImageView.leadingAnchor.constraint(equalTo: mainImageView.leadingAnchor, constant: vDepth / 2.0),
                  bottomImageView.topAnchor.constraint(equalTo: mainImageView.bottomAnchor, constant: 0.0),
                  bottomImageView.widthAnchor.constraint(equalTo: mainImageView.widthAnchor, multiplier: 1.0),
                  bottomImageView.heightAnchor.constraint(equalToConstant: vDepth),
      
                  ])
      
          }
      
          override func viewDidLayoutSubviews() {
              super.viewDidLayoutSubviews()
      
              // run this on viewDidLayoutSubviews() so we have valid frame sizes
              if let sourceImg = UIImage(named: "goal3x2") {
      
                  // resize image to width and height of main image view, plus vDepth value
                  let mainImg = resizeImage(image: sourceImg, newSize: CGSize(width: mainImageView.frame.width + vDepth, height: mainImageView.frame.height + vDepth))
      
                  // set the main image
                  mainImageView.image = mainImg
      
                  // we're going to darken the right-side and bottom images a little bit
                  if let currentFilter = CIFilter(name: "CIColorControls") {
                      let context = CIContext(options: nil)
      
                      let beginImage = CIImage(image: mainImg)
                      currentFilter.setValue(beginImage, forKey: kCIInputImageKey)
      
                      // darken right-image by 40%
                      currentFilter.setValue(-0.4, forKey: kCIInputBrightnessKey)
      
                      if let output = currentFilter.outputImage {
                          if let cgimg = context.createCGImage(output, from: output.extent) {
                              let processedImage = UIImage(cgImage: cgimg)
                              // set the right-side image
                              rightImageView.image = processedImage
                          }
                      }
      
                      // darken bottom-image by 50%
                      currentFilter.setValue(-0.5, forKey: kCIInputBrightnessKey)
      
                      if let output = currentFilter.outputImage {
                          if let cgimg = context.createCGImage(output, from: output.extent) {
                              let processedImage = UIImage(cgImage: cgimg)
                              // set the bottom image
                              bottomImageView.image = processedImage
                          }
                      }
                  }
      
              }
      
              // skew the right-side and bottom image views
              let skewVal: CGFloat = 1.0
      
              // bottom part transform
              let bottomTransform = CGAffineTransform(a: 1.0, b: 0.0, c: skewVal, d: 1.0, tx: 0.0, ty: 0.0)
              bottomImageView.transform = bottomTransform
      
              // right part transform
              let rightTransform = CGAffineTransform(a: 1.0, b: skewVal, c: 0.0, d: 1.0, tx: 0.0, ty: 0.0)
              rightImageView.transform = rightTransform
      
          }
      
          func resizeImage(image: UIImage, newSize: CGSize) -> UIImage {
      
              let newWidth = newSize.width
              let newHeight = newSize.height
              UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
              image.draw(in: CGRect(x: 0.0, y: 0.0, width: newWidth, height: newHeight))
              let newImage = UIGraphicsGetImageFromCurrentImageContext()
              UIGraphicsEndImageContext()
      
              return newImage!
          }
      
      }
      

      这是结果:

      有一个名为vDepth的变量,它控制着imageViews右侧的宽度和底部的高度。

      注意:这只是示例代码...希望这能让您顺利上路。

      【讨论】:

      • 感谢 donMag 的回答。但它需要在右上角的镜像。
      猜你喜欢
      • 2015-09-28
      • 2015-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-22
      • 1970-01-01
      • 2014-10-13
      • 1970-01-01
      相关资源
      最近更新 更多