Сделайте так, чтобы скользящий вид оставался в границах фонового просмотра - PullRequest
0 голосов
/ 28 мая 2020

Мне нужно сделать ползунок, чтобы пользователь двигался влево и вправо, чтобы подтвердить, что он хочет что-то купить enter image description here

Я перемещаю ползунок, обновляя смещение ведущего ограничения. Проблема в том, что я не могу заставить слайдер оставаться в границах фонового представления. Я пытался сохранить текущее смещение и проверять разницу координат после каждого касания, но это не сработало.

 var diff: CGFloat {
        return startCoordinate - endCoordinate
    }

private func updateConstraints(_ diff: CGFloat) {
        if diff + appearance.sliderLeadingOffset + currentOffset <= appearance.sliderMaxLeadingOffset {
            sliderView.snp.updateConstraints { make in
                make.leading.equalTo(backgroundView.snp.leading).offset(-diff)
            }
            startCoordinate = diff
            currentOffset = diff + appearance.sliderLeadingOffset
        }

    }

    @objc private func handlePan(_ gestureRecognizer: UIPanGestureRecognizer) {
        switch gestureRecognizer.state {
        case .began:
            let touchLocation = gestureRecognizer.location(in: sliderView)
            touchOffset = sliderView.bounds.minX + touchLocation.x
            startCoordinate = touchLocation.x - touchOffset
        case .ended:
            endCoordinate = gestureRecognizer.location(in: sliderView).x
        case .changed:
            let location = gestureRecognizer.location(in: sliderView)
            if backgroundView.frame.contains(location) {
                endCoordinate = location.x - touchOffset
            }
            updateConstraints(diff)
        default: break
        }
    }

1 Ответ

1 голос
/ 28 мая 2020

Ниже приведен полный код полностью работающей кнопки слайдера. Создайте новый файл Swift и назовите его SlidingButton.swift

import Foundation
import UIKit

protocol SlideButtonDelegate{
    func buttonStatus(status:String, sender:SlidingButton)
}

@IBDesignable class SlidingButton: UIView{

var delegate: SlideButtonDelegate?

@IBInspectable var dragPointWidth: CGFloat = 100 {
    didSet{
        setStyle()
    }
}

@IBInspectable var dragPointColor: UIColor = UIColor.darkGray {
    didSet{
        setStyle()
    }
}

@IBInspectable var buttonColor: UIColor = UIColor.gray {
    didSet{
        setStyle()
    }
}

@IBInspectable var buttonText: String = "Slide Here" {
    didSet{
        setStyle()
    }
}

@IBInspectable var imageName: UIImage = UIImage() {
    didSet{
        setStyle()
    }
}

@IBInspectable var buttonTextColor: UIColor = UIColor.white {
    didSet{
        setStyle()
    }
}

@IBInspectable var dragPointTextColor: UIColor = UIColor.white {
    didSet{
        setStyle()
    }
}

@IBInspectable var buttonFinishedSliding: UIColor = UIColor.white {
    didSet{
        setStyle()
    }
}

@IBInspectable var buttonCornerRadius: CGFloat = 30 {
    didSet{
        setStyle()
    }
}

var buttonFont = UIFont.boldSystemFont(ofSize: 35)

var dragPoint = UIView()
var buttonLabel = UILabel()
var dragPointButtonLabel = UILabel()
var imageView = UIImageView()
var layoutSet = false

override init (frame : CGRect) {
    super.init(frame : frame)
}

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)!

}

override func layoutSubviews() {
    if !layoutSet{
        self.setUpButton()
        self.layoutSet = true
    }
}

func setStyle(){
    self.buttonLabel.text = self.buttonText
    self.dragPointButtonLabel.text = self.buttonText
    self.dragPoint.frame.size.width = self.dragPointWidth
    self.dragPoint.backgroundColor = self.dragPointColor
    self.backgroundColor = self.buttonColor
    self.imageView.image = imageName
    self.buttonLabel.textColor = self.buttonTextColor
    self.dragPointButtonLabel.textColor = self.dragPointTextColor

    self.dragPoint.layer.cornerRadius = buttonCornerRadius
    self.layer.cornerRadius = buttonCornerRadius
}

func setUpButton(){

    self.backgroundColor = self.buttonColor
    self.dragPoint = UIView(frame: CGRect(x: dragPointWidth - self.frame.size.width, y: 0, width: self.frame.size.width, height: self.frame.size.height))
    self.dragPoint.backgroundColor = dragPointColor
    self.dragPoint.layer.cornerRadius = buttonCornerRadius
    self.addSubview(self.dragPoint)

    if !self.buttonText.isEmpty{

        self.buttonLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height))
        self.buttonLabel.textAlignment = .center
        self.buttonLabel.text = buttonText
        self.buttonLabel.textColor = UIColor.white
        self.buttonLabel.font = self.buttonFont
        self.buttonLabel.textColor = self.buttonTextColor
        self.addSubview(self.buttonLabel)

        self.dragPointButtonLabel = UILabel(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height))
        self.dragPointButtonLabel.textAlignment = .center
        self.dragPointButtonLabel.text = buttonText
        self.dragPointButtonLabel.textColor = UIColor.white
        self.dragPointButtonLabel.font = self.buttonFont
        self.dragPointButtonLabel.textColor = self.dragPointTextColor
        self.dragPoint.addSubview(self.dragPointButtonLabel)
    }
    self.bringSubviewToFront(self.dragPoint)

    if self.imageName != UIImage(){
        self.imageView = UIImageView(frame: CGRect(x: self.frame.size.width - dragPointWidth, y: 0, width: self.dragPointWidth, height: self.frame.size.height))
        self.imageView.contentMode = .center
        self.imageView.image = self.imageName
        self.dragPoint.addSubview(self.imageView)
    }

    self.layer.masksToBounds = true

    // start detecting pan gesture
    let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.panDetected(sender:)))
    panGestureRecognizer.minimumNumberOfTouches = 1
    self.dragPoint.addGestureRecognizer(panGestureRecognizer)
}

@objc func panDetected(sender: UIPanGestureRecognizer){
    var translatedPoint = sender.translation(in: self)
    translatedPoint     = CGPoint(x: translatedPoint.x, y: self.frame.size.height / 2)
    sender.view?.frame.origin.x = (dragPointWidth - self.frame.size.width) + translatedPoint.x
    if sender.state == .ended{

        let velocityX = sender.velocity(in: self).x * 0.2
        var finalX = translatedPoint.x + velocityX
        if finalX < 0{
            finalX = 0
        }else if finalX + self.dragPointWidth  >  (self.frame.size.width - 60){
            // final point reached, do somethign here
        }

        let animationDuration:Double = abs(Double(velocityX) * 0.0002) + 0.2
        UIView.transition(with: self, duration: animationDuration, options: UIView.AnimationOptions.curveEaseOut, animations: {
            }, completion: { (Status) in
                if Status{
                    self.animationFinished()
                }
        })
    }
}
}

ИСПОЛЬЗОВАНИЕ:

Добавьте UIVIEW и приведите его в соответствие с приведенным выше классом SlidingButton

Затем вы можете настроить как необходимо использовать раскадровку

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...