【问题标题】:How to set UIScrollView like 3D Square如何像 3D Square 一样设置 UIScrollView
【发布时间】:2018-07-20 09:44:54
【问题描述】:

我正在开发照片编辑应用程序,我有 3 个带有 UIImageview 的 ScrollViews,我想将 ScrollViews 设置为以下

我曾尝试过“Scenekit”,但它不起作用,因为我想要 ScrollableView。

基本上我想创建 3D 拼贴
有没有其他方法可以做到这一点?

是否可以像 3d Square 一样设置 UIScrollView?

【问题讨论】:

    标签: ios swift 3d uiimageview


    【解决方案1】:

    我使用 CATransform3D 使用以下代码实现这一点

    我在 StoryBoard 中用 UIImageview 创建了 3 个 Scrollview

    @IBOutlet var faces: [UIView]!
    

    ViewDidiLoad

        var perspective: CATransform3D = CATransform3DIdentity
        perspective.m34 = -1.0 / 500.0
    
        self.view?.layer.sublayerTransform = perspective
    
        perspective = CATransform3DRotate(perspective, CGFloat(-Double.pi / 4), 1, 0, 0)
        perspective = CATransform3DRotate(perspective, CGFloat(-Double.pi / 4), 0, 1, 0)
    
        print(perspective)
    
        self.view.layer.sublayerTransform = perspective
    
        //add cube face 1
        var transform: CATransform3D = CATransform3DMakeTranslation(0, 0, 50)
        addFace(0, withTransform: transform)
    
        //add cube face 2
        transform = CATransform3DMakeTranslation(50, 0, 0)
        transform = CATransform3DRotate(transform, CGFloat(Double.pi / 2), 0, 1, 0)
    
        addFace(1, withTransform: transform)
    
        //add cube face 3
        transform = CATransform3DMakeTranslation(0, -50, 0)
        transform = CATransform3DRotate(transform, CGFloat(Double.pi / 2), 1, 0, 0)
    
        addFace(2, withTransform: transform)
    

    添加人脸功能

    func addFace(_ index: Int, withTransform transform: CATransform3D) {
        let face: UIView? = faces[index]
    
        if let aFace = face {
            self.view.addSubview(aFace)
        }
    
        let containerSize: CGSize? = self.view.bounds.size
    
        face?.center = CGPoint(x: (containerSize?.width ?? 0.0) / 2.0, y: (containerSize?.height ?? 0.0) / 2.0)
        face?.layer.transform = transform
    }
    

    输出

    【讨论】:

      【解决方案2】:

      似乎你需要有手势来旋转立方体来调整拼贴。所以你不能只为达到同样的目的而使用 UIKit。

      从 UIKit 坐标转换为 SceneKit 坐标是您要求的挑战。

      相反,您需要使用 SceneKit 和 UIKit 来完成同样的工作。

      按照以下步骤进行

      使用 SceneKit 创建立方体 UI

      import UIKit
      import SceneKit
      
      class ViewController: UIViewController {
      
      @IBOutlet weak var mySceneView: SCNView!
      override func viewDidLoad() {
          super.viewDidLoad()
          mySceneView.allowsCameraControl = true
          //Create instance of scene
          let scene = SCNScene()
          mySceneView.scene = scene
          //Add cube to scnview
          AddCubeToScene()
      }
      
      override func didReceiveMemoryWarning() {
          super.didReceiveMemoryWarning()
          // Dispose of any resources that can be recreated.
      }
      
      func AddCubeToScene()
      {
          //Create a box of size 0.1 * 0.1 * 0.1
          let myBox = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)
          myBox.firstMaterial?.diffuse.contents = UIColor.red
          myBox.firstMaterial?.isDoubleSided = true
          //Create SCnnode of from geometry and specified its position
          let cubeNode = SCNNode(geometry: myBox)
          //Add created scnnode to scene
          mySceneView.scene?.rootNode.addChildNode(cubeNode)
      }
      }
      

      使用 UIKit 创建 UIScrollView

      weak var scrollView: UIScrollView?
      
      override func viewDidLoad() {
      super.viewDidLoad()
      
      let scrollView = UIScrollView(frame: CGRect.zero)
      scrollView.contentSize = contentSize
      scrollView.delegate = self
      scrollView.minimumZoomScale = 1
      scrollView.maximumZoomScale = 3
      scrollView.indicatorStyle = .white
      self.scrollView = scrollView
      
      let clearContentView = UIView(frame: CGRect(x: 0, y: 0, width: contentSize.width, height: contentSize.height))
          clearContentView.backgroundColor = UIColor.clear
          scrollView.addSubview(clearContentView)
          self.clearContentView = clearContentView
          clearContentView.addObserver(self, forKeyPath: "transform", options: .new, context: &ViewTransformChangedObservationContext)
          skView.addSubview(scrollView)
      }
      
      override func viewWillLayoutSubviews() {
          super.viewWillLayoutSubviews()
          scrollView?.frame = view.bounds
          scene?.size = view.bounds.size
          if let scrollView = scrollView {
              adjustContent(scrollView: scrollView)
          }
      }
      
      func adjustContent(scrollView: UIScrollView) {
          let zoomScale = scrollView.zoomScale
          scene?.setContentScale(scale: zoomScale)
          let contentOffset = scrollView.contentOffset
          let contentSize = scrollView.contentSize
          let scrollAreaHeight: CGFloat = contentSize.height - scrollView.bounds.height
          let yUIKit: CGFloat = contentOffset.y
      
          // Convert from UIKit coordinates to SpriteKit coordinates
          // UIKit has 0,0 in the top-left corner
          // SpriteKit has 0,0 in the bottom-left corner
          let ySpriteKit = scrollAreaHeight - yUIKit
          let contentOffsetSpriteKit = CGPoint(x: contentOffset.x, y: ySpriteKit)
          scene?.contentOffset = contentOffsetSpriteKit
      }
      
      func scrollViewDidScroll(_ scrollView: UIScrollView) {
          adjustContent(scrollView: scrollView)
      }
      
      func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
          return clearContentView
      }
      
      func scrollViewDidTransform(scrollView: UIScrollView) {
          adjustContent(scrollView: scrollView)
      }
      
      // scale between minimum and maximum. called after any 'bounce' animations
      func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
          adjustContent(scrollView: scrollView)
      }
      

      现在将UIScrollView 实例添加到立方体的每一侧(即子节点)

      你在那儿!

      【讨论】:

        【解决方案3】:

        您正在寻找的解决方案可能是一个框架。 你可以看看这些开源项目。 MKCubeControllerCubeControllerGemini.

        CubeController 是最接近您要求的,您可能需要稍微修改一下。 Gemini 也有立方体实现。

        【讨论】:

        • 嘿,我认为这都是关于导航的。我不想浏览它。我正在创建照片编辑应用程序,所以现在您可以了解我到底想要什么。
        猜你喜欢
        • 1970-01-01
        • 2012-08-27
        • 1970-01-01
        • 2012-03-02
        • 1970-01-01
        • 2016-07-17
        • 2020-04-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多