Last active
July 31, 2017 09:23
-
-
Save victor-pavlychko/d7c91fc6701de7bf56edff1791edd50b to your computer and use it in GitHub Desktop.
UIView extension to maintain z-ordering in a superview
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ZIndexedView.swift | |
// | |
// Created by Victor Pavlychko on 7/30/17. | |
// Copyright © 2017. All rights reserved. | |
// | |
import UIKit | |
public protocol ZIndexed { | |
var zIndex: CGFloat { get } | |
} | |
public extension ZIndexed where Self: UIView { | |
public func didUpdateZIndex(_ zIndex: CGFloat, from oldValue: CGFloat) { | |
if zIndex != oldValue { | |
didUpdateZIndex() | |
} | |
} | |
public func didUpdateZIndex() { | |
guard let superview = superview else { | |
return | |
} | |
let siblings = superview.subviews.filter({ $0 !== self }) | |
if let insertionPoint = findInsertionPoint(in: siblings) { | |
superview.insertSubview(self, belowSubview: insertionPoint) | |
} else { | |
superview.addSubview(self) | |
} | |
} | |
private func findInsertionPoint(in input: [UIView]) -> UIView? { | |
var lowerIndex = -1 | |
var upperIndex = input.count | |
while upperIndex - lowerIndex > 1 { | |
let currentIndex = (lowerIndex + upperIndex) / 2 | |
if (input[currentIndex] as? ZIndexed)?.zIndex ?? 0 > zIndex { | |
upperIndex = currentIndex | |
} else { | |
lowerIndex = currentIndex | |
} | |
} | |
return upperIndex < input.count ? input[upperIndex] : nil | |
} | |
} | |
open class ZIndexedCollectionViewCell: UICollectionViewCell, ZIndexed { | |
open var zIndex: CGFloat = 0 { | |
didSet { didUpdateZIndex(zIndex, from: oldValue) } | |
} | |
open override func didMoveToSuperview() { | |
super.didMoveToSuperview() | |
didUpdateZIndex() | |
} | |
open override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) { | |
super.apply(layoutAttributes) | |
zIndex = CGFloat(layoutAttributes.zIndex) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment