Skip to content

Instantly share code, notes, and snippets.

@victor-pavlychko
Last active July 31, 2017 09:23
Show Gist options
  • Save victor-pavlychko/d7c91fc6701de7bf56edff1791edd50b to your computer and use it in GitHub Desktop.
Save victor-pavlychko/d7c91fc6701de7bf56edff1791edd50b to your computer and use it in GitHub Desktop.
UIView extension to maintain z-ordering in a superview
//
// 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