Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import UIKit
- enum SeparatorType {
- case Horisontal
- case Vertical
- }
- let kTotalSize: CGFloat = 44; // the total height of the separator (including parts that are not visible
- let kVisibleSize: CGFloat = 10; // the height of the visible portion of the separator
- let kMargin: CGFloat = (kTotalSize - kVisibleSize) / 2.0; // the height of the non-visible portions of the separator (i.e. above and below the visible portion)
- let kMinSize: CGFloat = 10; // the minimum height allowed for views above and below the separator
- protocol OnConstraintsUpdateProtocol {
- func updateConstraintOnBasisOfTouch(touch: UITouch)
- }
- class SeparatorView: UIView {
- var startConstraint: NSLayoutConstraint? // the constraint that dictates the vertical position of the separator
- var primaryView: UIView // the view above the separator
- var secondaryView: UIView // the view below the separator
- // some properties used for handling the touches
- var oldPosition: CGFloat = 0.0 // the position of the separator before the gesture started
- var firstTouch: CGPoint? // the position where the drag gesture started
- var updateListener: OnConstraintsUpdateProtocol?
- internal static func addSeparatorBetweenViews(separatorType: SeparatorType, primaryView: UIView, secondaryView: UIView, parentView: UIView) -> SeparatorView {
- var separator: SeparatorView
- if (separatorType == .Horisontal) {
- separator = HorizontalSeparatorView(primaryView: primaryView, secondaryView: secondaryView)
- } else {
- separator = VerticalSeparatorView(primaryView: primaryView, secondaryView: secondaryView)
- }
- separator.setupParentViewConstraints(parentView)
- parentView.addSubview(separator)
- separator.setupSeparatorConstraints()
- return separator
- }
- init(primaryView: UIView, secondaryView: UIView){
- self.primaryView = primaryView
- self.secondaryView = secondaryView
- super.init(frame: CGRectZero)
- self.translatesAutoresizingMaskIntoConstraints = false
- self.userInteractionEnabled = true
- self.backgroundColor = UIColor.clearColor()
- }
- func setupParentViewConstraints(parentView: UIView){}
- func setupSeparatorConstraints(){}
- required init?(coder aDecoder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
- self.firstTouch = touches.first?.locationInView(self.superview)
- self.startConstraint!.constant = self.oldPosition;
- self.startConstraint!.active = true;
- }
- override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
- guard let touch = touches.first, event = event else { return }
- // for more responsive UX, use predicted touches, if possible
- let predictedTouch = event.predictedTouchesForTouch(touch)?.last
- if ((predictedTouch) != nil) {
- updateListener?.updateConstraintOnBasisOfTouch(predictedTouch!)
- return;
- }
- // if no predicted touch found, just use the touch provided
- updateListener?.updateConstraintOnBasisOfTouch(touch)
- }
- override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
- guard let touch = touches.first else { return }
- updateListener?.updateConstraintOnBasisOfTouch(touch)
- }
- override func drawRect(rect: CGRect) {
- let path = UIBezierPath(rect: rect)
- UIColor.blackColor().set()
- path.stroke()
- path.fill()
- }
- }
- class HorizontalSeparatorView: SeparatorView, OnConstraintsUpdateProtocol {
- override init(primaryView: UIView, secondaryView: UIView) {
- super.init(primaryView: primaryView, secondaryView: secondaryView)
- updateListener = self
- }
- required init?(coder aDecoder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- override func setupParentViewConstraints(parentView: UIView) {
- parentView.leadingAnchor.constraintEqualToAnchor(primaryView.leadingAnchor).active = true
- parentView.trailingAnchor.constraintEqualToAnchor(primaryView.trailingAnchor).active = true
- parentView.leadingAnchor.constraintEqualToAnchor(secondaryView.leadingAnchor).active = true
- parentView.trailingAnchor.constraintEqualToAnchor(secondaryView.trailingAnchor).active = true
- parentView.topAnchor.constraintEqualToAnchor(primaryView.topAnchor).active = true
- let height = secondaryView.heightAnchor.constraintEqualToAnchor(primaryView.heightAnchor)
- height.priority = 250
- height.active = true
- parentView.bottomAnchor.constraintEqualToAnchor(secondaryView.bottomAnchor).active = true
- }
- override func setupSeparatorConstraints() {
- self.heightAnchor.constraintEqualToConstant(kTotalSize).active = true
- self.superview?.leadingAnchor.constraintEqualToAnchor(self.leadingAnchor).active = true
- self.superview?.trailingAnchor.constraintEqualToAnchor(self.trailingAnchor).active = true
- primaryView.bottomAnchor.constraintEqualToAnchor(self.topAnchor, constant: kMargin).active = true
- secondaryView.topAnchor.constraintEqualToAnchor(self.bottomAnchor, constant: -kMargin).active = true
- startConstraint = self.topAnchor.constraintEqualToAnchor(self.superview?.topAnchor, constant: 0)
- }
- override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
- self.oldPosition = self.frame.origin.y;
- super.touchesBegan(touches, withEvent: event)
- }
- override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
- super.touchesMoved(touches, withEvent: event)
- }
- override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
- super.touchesEnded(touches, withEvent: event)
- }
- func updateConstraintOnBasisOfTouch(touch: UITouch) {
- // calculate where separator should be moved to
- var y: CGFloat = self.oldPosition + touch.locationInView(self.superview).y - self.firstTouch!.y
- // make sure the views above and below are not too small
- y = max(y, self.primaryView.frame.origin.y + kMinSize - kMargin)
- y = min(y, self.secondaryView.frame.origin.y + self.secondaryView.frame.size.height - (kMargin + kMinSize))
- // set constraint
- self.startConstraint!.constant = y
- }
- override func drawRect(rect: CGRect) {
- let separatorRect = CGRectMake(0, kMargin, self.bounds.size.width, kVisibleSize)
- super.drawRect(separatorRect)
- }
- }
- class VerticalSeparatorView: SeparatorView, OnConstraintsUpdateProtocol {
- override init(primaryView: UIView, secondaryView: UIView) {
- super.init(primaryView: primaryView, secondaryView: secondaryView)
- updateListener = self
- }
- required init?(coder aDecoder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- override func setupParentViewConstraints(parentView: UIView) {
- parentView.topAnchor.constraintEqualToAnchor(primaryView.topAnchor).active = true
- parentView.topAnchor.constraintEqualToAnchor(secondaryView.topAnchor).active = true
- parentView.bottomAnchor.constraintEqualToAnchor(primaryView.bottomAnchor).active = true
- parentView.leadingAnchor.constraintEqualToAnchor(secondaryView.topAnchor).active = true
- parentView.bottomAnchor.constraintEqualToAnchor(secondaryView.bottomAnchor).active = true
- parentView.leadingAnchor.constraintEqualToAnchor(primaryView.leadingAnchor).active = true
- let width = secondaryView.widthAnchor.constraintEqualToAnchor(primaryView.widthAnchor)
- width.priority = 250
- width.active = true
- parentView.trailingAnchor.constraintEqualToAnchor(secondaryView.trailingAnchor).active = true
- }
- override func setupSeparatorConstraints() {
- self.widthAnchor.constraintEqualToConstant(kTotalSize).active = true
- self.superview?.topAnchor.constraintEqualToAnchor(self.topAnchor).active = true
- self.superview?.bottomAnchor.constraintEqualToAnchor(self.bottomAnchor).active = true
- primaryView.trailingAnchor.constraintEqualToAnchor(self.leadingAnchor, constant: kMargin).active = true
- secondaryView.leadingAnchor.constraintEqualToAnchor(self.trailingAnchor, constant: -kMargin).active = true
- startConstraint = self.leadingAnchor.constraintEqualToAnchor(self.superview?.leadingAnchor, constant: 0)
- }
- override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
- self.oldPosition = self.frame.origin.x;
- super.touchesBegan(touches, withEvent: event)
- }
- override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
- super.touchesMoved(touches, withEvent: event)
- }
- override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
- super.touchesEnded(touches, withEvent: event)
- }
- func updateConstraintOnBasisOfTouch(touch: UITouch) {
- // calculate where separator should be moved to
- var x: CGFloat = self.oldPosition + touch.locationInView(self.superview).x - self.firstTouch!.x
- // make sure the views above and below are not too small
- x = max(x, self.primaryView.frame.origin.x + kMinSize - kMargin)
- x = min(x, self.secondaryView.frame.origin.x + self.secondaryView.frame.size.width - (kMargin + kMinSize))
- // set constraint
- self.startConstraint!.constant = x
- }
- override func drawRect(rect: CGRect) {
- let separatorRect = CGRectMake(kMargin, 0, kVisibleSize, self.bounds.size.height)
- super.drawRect(separatorRect)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement