如何仅在SwiftUI中使用按钮移动滚动视图

时间:2020-05-01 12:06:36

标签: swiftui

以前,我是使用 Swift4 UIScrollView进行的,该UIScrollView可以滚动按钮和x偏移量。 enter image description here

Swift4 中,我有:

  1. Scrolling EnabledPaging Enabled设置为false。

    List item

  2. UIScrollView中为每帧创建页边距和偏移量,并使用按钮BackNext更改位置。

代码如下:

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var buttonSound: UIButton!
@IBOutlet weak var buttonPrev: UIButton!
@IBOutlet weak var buttonNext: UIButton!
@IBOutlet weak var scrollView: UIScrollView!

var levels = ["level1", "level2", "level3", "level4"]
let screenWidth = UIScreen.main.bounds.width
let screenHeight = UIScreen.main.bounds.height
var currentLevel = 1
var previousLevel: Int? = nil

override func viewDidLoad() {
    super.viewDidLoad()

    //Defining the Various Swipe directions (left, right, up, down)
    let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(self.handleGesture(gesture:)))
      swipeLeft.direction = .left
    self.view.addGestureRecognizer(swipeLeft)

    let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.handleGesture(gesture:)))
    swipeRight.direction = .right
    self.view.addGestureRecognizer(swipeRight)

    addHorizontalLevelsList()
    customizeButtons()
    resizeSelected()
}

func addHorizontalLevelsList() {

    var frame : CGRect?
    for i in 0..<levels.count {

        let button = UIButton(type: .custom)
        let buttonW = screenWidth/3
        let buttonH = screenHeight/2

        frame = CGRect(x: CGFloat(i+1) * (screenWidth/2) - (buttonW/2),
                       y: buttonH - 100,
                       width: buttonW,
                       height: buttonH)

        button.frame = frame!
        button.tag = i+1
        button.backgroundColor = .lightGray
        button.addTarget(self, action: #selector(selectTeam), for: .touchUpInside)
        button.setTitle(levels[i], for: .normal)
        scrollView.addSubview(button)
    }


    scrollView.contentSize = CGSize(width: (screenWidth/2 * CGFloat(levels.count)),
                                    height: screenHeight)
    scrollView.backgroundColor = .clear
    self.view.addSubview(scrollView)
}


func customizeButtons(){
    buttonPrev.frame = CGRect(x: 0,
                              y: (screenHeight/2) - 40,
                              width: 80, height: 80)
    buttonNext.frame = CGRect(x: screenWidth - 80,
                              y: (screenHeight/2) - 40,
                              width: 80, height: 80)
    buttonPrev.superview?.bringSubviewToFront(buttonPrev)
    buttonNext.superview?.bringSubviewToFront(buttonNext)
}

@objc func selectTeam(button: UIButton) {
    button.transform = CGAffineTransform(scaleX: 0.6, y: 0.6)
    UIView.animate(withDuration: 1.0,
                               delay: 0,
                               usingSpringWithDamping: CGFloat(0.20),
                               initialSpringVelocity: CGFloat(6.0),
                               options: UIView.AnimationOptions.allowUserInteraction,
                               animations: {
                                button.transform = CGAffineTransform.identity
        },
                               completion: { Void in()  }
    )

    print(levels[button.tag])

    let vc = PopTypeVC(nibName: "PopTypeVC", bundle: nil)
    vc.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
    self.present(vc, animated: true)
}

@IBAction func prevLevel(_ sender: Any) {
    if currentLevel > 0 {

        currentLevel -= 1
        scroll()
    }
}
@IBAction func nextLevel(_ sender: Any) {
    if currentLevel < levels.count {

        currentLevel += 1
        scroll()
    }
}

func scroll(){
    print(currentLevel)
    print(previousLevel as Any)

    scrollView.setContentOffset(CGPoint(x: currentLevel * Int(screenWidth/2), y: 0), animated: true)
    resizeSelected()
}

// The @objc before func is a must, since we are using #selector (above)
@objc func handleGesture(gesture: UISwipeGestureRecognizer) -> Void {
    if gesture.direction == UISwipeGestureRecognizer.Direction.right {
        prevLevel(self)
    }
    else if gesture.direction == UISwipeGestureRecognizer.Direction.left {
        nextLevel(self)
    }
}

func resizeSelected(){
    if previousLevel != nil {
        let previousFrame = CGRect(x:CGFloat(previousLevel!) * (screenWidth/2) - (screenWidth/3)/2,
                                   y:        (screenHeight/2) - 100,
                                   width:    screenWidth/3,
                                   height:   screenHeight/2)
        scrollView.viewWithTag(previousLevel!)?.frame = previousFrame
    }

    let currentFrame = CGRect(x: CGFloat(currentLevel) * (screenWidth/2) - (screenWidth/3)/2 - 10,
                              y:        (screenHeight/2) - 110,
                              width:    screenWidth/3 + 20,
                              height:   screenHeight/2 + 20)
    scrollView.viewWithTag(currentLevel)?.frame = currentFrame
        previousLevel = currentLevel
    }
}

问题是我无法使用SwiftUI:

struct ContentView: View {

    static var levels = ["level1",
                  "level2",
                  "level3",
                  "level4"]
    var currentLevel = 1
    var previousLevel: Int? = nil

    let screenW = UIScreen.main.bounds.width
    let screenH = UIScreen.main.bounds.height
    let margin1 = 50
    let margin2 = 100
    let margin3 = 20
    let sceneButtonW = 100
    let buttonPadding = 40

    var body: some View {

        ZStack {

            // Horizontal list
            VStack {
                Spacer()
                    .frame(height: margin2)
                ScrollView(.horizontal, showsIndicators: false) {

                    HStack{
                        Spacer()
                            .frame(width: buttonPadding + sceneButtonW/2)
                        ForEach(0..<ContentView.levels.count) { i in
                            cardView(i: i).tag(i+1)
                        }
                        Spacer()
                            .frame(width: buttonPadding + sceneButtonW/2)
                    }

                }
                Spacer()
                    .frame(height: margin3)
            }

        }
        .background(Image("bg")
        .resizable()
        .edgesIgnoringSafeArea(.all)
        .aspectRatio(contentMode: .fill))
    }
}

问题:是否有任何方法可以完全禁用自动滚动并在SwiftUI和SwiftUI上使用偏移量?

1 个答案:

答案 0 :(得分:0)

这个已经为SwiftUI构建的解决方案

https://github.com/fermoya/SwiftUIPager

但是,没有真实的例子。