Skip to content

Commit

Permalink
rtl support
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmedk92 committed Jul 12, 2020
1 parent 444b4ea commit 06fc20a
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 26 deletions.
2 changes: 2 additions & 0 deletions Example/liquid-swipe/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class ViewController: LiquidSwipeContainerController, LiquidSwipeContainerDataSo
}()

override func viewDidLoad() {
// Uncomment for testing RTL
// view.semanticContentAttribute = .forceRightToLeft
super.viewDidLoad()
datasource = self
}
Expand Down
91 changes: 66 additions & 25 deletions liquid-swipe/Classes/LiquidSwipeContainerController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ open class LiquidSwipeContainerController: UIViewController {
private var animating: Bool = false
private var duration: CFTimeInterval = 0.8

private var rightEdgeGesture = UIScreenEdgePanGestureRecognizer()
private var leftEdgeGesture = UIScreenEdgePanGestureRecognizer()
private var trailingEdgeGesture = UIScreenEdgePanGestureRecognizer()
private var leadingEdgeGesture = UIScreenEdgePanGestureRecognizer()

private var csBtnNextLeading: NSLayoutConstraint?
private var csBtnNextCenterY: NSLayoutConstraint?
Expand All @@ -91,14 +91,14 @@ open class LiquidSwipeContainerController: UIViewController {
}

private func configureGestures() {
rightEdgeGesture.addTarget(self, action: #selector(rightEdgePan))
rightEdgeGesture.edges = .right
view.addGestureRecognizer(rightEdgeGesture)
trailingEdgeGesture.addTarget(self, action: #selector(trailingEdgePan))
trailingEdgeGesture.edges = view.trailingEdge
view.addGestureRecognizer(trailingEdgeGesture)

leftEdgeGesture.addTarget(self, action: #selector(leftEdgePan))
leftEdgeGesture.edges = .left
view.addGestureRecognizer(leftEdgeGesture)
leftEdgeGesture.isEnabled = false
leadingEdgeGesture.addTarget(self, action: #selector(leadingEdgePan))
leadingEdgeGesture.edges = view.leadingEdge
view.addGestureRecognizer(leadingEdgeGesture)
leadingEdgeGesture.isEnabled = false
}

private func animate(view: UIView, forProgress progress: CGFloat, waveCenterY: CGFloat? = nil) {
Expand Down Expand Up @@ -137,7 +137,7 @@ open class LiquidSwipeContainerController: UIViewController {
private var shouldFinish: Bool = false
private var shouldCancel: Bool = false
private var animationProgress: CGFloat = 0.0
@objc private func rightEdgePan(_ sender: UIPanGestureRecognizer) {
@objc private func trailingEdgePan(_ sender: UIPanGestureRecognizer) {
guard !animating else {
return
}
Expand All @@ -162,7 +162,7 @@ open class LiquidSwipeContainerController: UIViewController {
let direction: CGFloat = (gesture.location(in: view).y - mask.waveCenterY).sign == .plus ? 1 : -1
let distance = min(CGFloat(time) * speed, abs(mask.waveCenterY - gesture.location(in: view).y))
let centerY = mask.waveCenterY + distance * direction
let change = -gesture.translation(in: view).x
let change = -gesture.translation(in: view).x.flipped(for: self.view)
let maxChange: CGFloat = self.view.bounds.width * (1.0/0.45)
if !(self.shouldFinish || self.shouldCancel) {
let progress: CGFloat = min(1.0, max(0, change / maxChange))
Expand Down Expand Up @@ -219,7 +219,7 @@ open class LiquidSwipeContainerController: UIViewController {
}
}

@objc private func leftEdgePan(_ sender: UIPanGestureRecognizer) {
@objc private func leadingEdgePan(_ sender: UIPanGestureRecognizer) {
guard !animating else {
return
}
Expand All @@ -245,7 +245,7 @@ open class LiquidSwipeContainerController: UIViewController {
let direction: CGFloat = (gesture.location(in: view).y - mask.waveCenterY).sign == .plus ? 1 : -1
let distance = min(CGFloat(time) * speed, abs(mask.waveCenterY - gesture.location(in: view).y))
let centerY = mask.waveCenterY + distance * direction
let change = gesture.translation(in: view).x
let change = gesture.translation(in: view).x.flipped(for: self.view)
let maxChange: CGFloat = self.view.bounds.width
if !(self.shouldFinish || self.shouldCancel) {
let progress: CGFloat = min(1.0, max(0, 1 - change / maxChange))
Expand Down Expand Up @@ -389,7 +389,13 @@ open class LiquidSwipeContainerController: UIViewController {
layoutPageView(firstPage)

if pagesCount > 1 {
let maskLayer = WaveLayer(waveCenterY: initialWaveCenter, waveHorRadius: initialHorRadius, waveVertRadius: initialVertRadius, sideWidth: initialSideWidth)
let maskLayer = WaveLayer(
waveCenterY: initialWaveCenter,
waveHorRadius: initialHorRadius,
waveVertRadius: initialVertRadius,
sideWidth: initialSideWidth,
isRTL: self.view.isRTL
)
apply(mask: maskLayer, on: firstPage)
}
currentViewController = firstVC
Expand All @@ -403,19 +409,21 @@ open class LiquidSwipeContainerController: UIViewController {
previousViewController = currentViewController
currentViewController = nextViewController
currentPageIndex += 1
leftEdgeGesture.isEnabled = true
leadingEdgeGesture.isEnabled = true
let maskLayer = WaveLayer(waveCenterY: initialWaveCenter,
waveHorRadius: 0,
waveVertRadius: initialVertRadius,
sideWidth: 0)
sideWidth: 0,
isRTL: self.view.isRTL
)
if let currentPage = currentPage {
apply(mask: maskLayer, on: currentPage)
}
configureNextPage()
setNeedsStatusBarAppearanceUpdate()
guard nextViewController != nil else {
btnNext.isHidden = true
rightEdgeGesture.isEnabled = false
trailingEdgeGesture.isEnabled = false
if let viewController = currentViewController {
delegate?.liquidSwipeContainer(self, didFinishTransitionTo: viewController, transitionCompleted: true)
}
Expand Down Expand Up @@ -457,17 +465,19 @@ open class LiquidSwipeContainerController: UIViewController {
currentViewController = previousViewController
currentPageIndex -= 1
btnNext.isHidden = false
rightEdgeGesture.isEnabled = true
trailingEdgeGesture.isEnabled = true
let maskLayer = WaveLayer(waveCenterY: initialWaveCenter,
waveHorRadius: 0,
waveVertRadius: maxVertRadius,
sideWidth: view.bounds.width)
sideWidth: view.bounds.width,
isRTL: self.view.isRTL
)
configurePreviousPage()
setNeedsStatusBarAppearanceUpdate()
if let prevPage = previousViewController?.view {
apply(mask: maskLayer, on: prevPage)
} else {
leftEdgeGesture.isEnabled = false
leadingEdgeGesture.isEnabled = false
}
let startTime = CACurrentMediaTime()
let duration: CFTimeInterval = 0.3
Expand Down Expand Up @@ -502,7 +512,7 @@ open class LiquidSwipeContainerController: UIViewController {
let pagesCount = datasource.numberOfControllersInLiquidSwipeContainer(self)
guard pagesCount > currentPageIndex + 1 else {
nextViewController = nil
rightEdgeGesture.isEnabled = false
trailingEdgeGesture.isEnabled = false
return
}
let nextVC = datasource.liquidSwipeContainer(self, viewControllerAtIndex: currentPageIndex + 1)
Expand All @@ -529,7 +539,7 @@ open class LiquidSwipeContainerController: UIViewController {
let pagesCount = datasource.numberOfControllersInLiquidSwipeContainer(self)
guard currentPageIndex > 0 && pagesCount > 0 else {
previousViewController = nil
leftEdgeGesture.isEnabled = false
leadingEdgeGesture.isEnabled = false
return
}
let previousVC = datasource.liquidSwipeContainer(self, viewControllerAtIndex: currentPageIndex - 1)
Expand Down Expand Up @@ -608,15 +618,25 @@ open class LiquidSwipeContainerController: UIViewController {
let hasNextPage = self.nextViewController != nil
let maskLayer = WaveLayer(waveCenterY: self.initialWaveCenter,
waveHorRadius: hasNextPage ? self.initialHorRadius : 0,
waveVertRadius: self.initialVertRadius, sideWidth: hasNextPage ?self.initialSideWidth : 0)
waveVertRadius: self.initialVertRadius, sideWidth: hasNextPage ? self.initialSideWidth : 0,
isRTL: self.view.isRTL
)
self.apply(mask: maskLayer, on: currentPage)
}
if let nextPage = self.nextViewController?.view {
let maskLayer = WaveLayer(waveCenterY: self.initialWaveCenter, waveHorRadius: 0, waveVertRadius: self.initialVertRadius, sideWidth: 0)
let maskLayer = WaveLayer(waveCenterY: self.initialWaveCenter, waveHorRadius: 0, waveVertRadius: self.initialVertRadius, sideWidth: 0,
isRTL: self.view.isRTL
)
self.apply(mask: maskLayer, on: nextPage)
}
if let prevPage = self.previousViewController?.view {
let maskLayer = WaveLayer(waveCenterY: self.initialWaveCenter, waveHorRadius: 0, waveVertRadius: self.initialVertRadius, sideWidth: prevPage.bounds.height)
let maskLayer = WaveLayer(
waveCenterY: self.initialWaveCenter,
waveHorRadius: 0,
waveVertRadius: self.initialVertRadius,
sideWidth: prevPage.bounds.height,
isRTL: self.view.isRTL
)
self.apply(mask: maskLayer, on: prevPage)
}
self.csBtnNextCenterY?.constant = self.initialWaveCenter
Expand Down Expand Up @@ -713,3 +733,24 @@ private extension LiquidSwipeContainerController {
return initialSideWidth + (view.bounds.width - initialSideWidth) * (progress - p1)/(p2 - p1)
}
}

private extension UIView {
var leadingEdge: UIRectEdge {
isRTL ? .right : .left
}
var trailingEdge: UIRectEdge {
isRTL ? .left : .right
}
var isRTL: Bool {
if #available(iOS 10.0, *) {
return effectiveUserInterfaceLayoutDirection == .rightToLeft
} else {
return false
}}
}

private extension FloatingPoint {
func flipped(for view: UIView) -> Self {
view.isRTL ? -self : self
}
}
11 changes: 10 additions & 1 deletion liquid-swipe/Classes/WaveLayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,21 @@ internal class WaveLayer: CAShapeLayer {
super.init(layer: layer)
}

init(waveCenterY: CGFloat, waveHorRadius: CGFloat, waveVertRadius: CGFloat, sideWidth: CGFloat) {
init(
waveCenterY: CGFloat,
waveHorRadius: CGFloat,
waveVertRadius: CGFloat,
sideWidth: CGFloat,
isRTL: Bool
) {
self.waveCenterY = waveCenterY
self.waveHorRadius = waveHorRadius
self.waveVertRadius = waveVertRadius
self.sideWidth = sideWidth
super.init()
if isRTL {
setAffineTransform(.init(scaleX: -1, y: 1))
}
}

func updatePath() {
Expand Down

0 comments on commit 06fc20a

Please sign in to comment.