Skip to content

Instantly share code, notes, and snippets.

@pr0zac
Created April 19, 2019 19:40
Show Gist options
  • Save pr0zac/0a2ef13c03c9fb48d85776bd4b50d1e0 to your computer and use it in GitHub Desktop.
Save pr0zac/0a2ef13c03c9fb48d85776bd4b50d1e0 to your computer and use it in GitHub Desktop.
//
// ProfilePictureGroupView.swift
// Vault
//
// Created by Cole Potrocky on 1/24/19.
// Copyright © 2019 Vault. All rights reserved.
//
import UIKit
final class ProfilePictureGroupView: UIView {
struct Wrapper: AutoEquatable {
let profilePictures: [ProfilePictureViewModel]
}
var preferredSize: CGSize = .zero {
didSet {
guard preferredSize != oldValue else { return }
invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
return preferredSize
}
var wrapper: Wrapper?
var needsRerender: Bool = false
func setImages(profilePictures: [ProfilePictureViewModel]) {
let newWrapper = Wrapper(profilePictures: profilePictures)
guard newWrapper != wrapper else { return }
wrapper = newWrapper
updateImageLayout()
}
func updateImageLayout() {
guard frame != .zero else {
needsRerender = true
return
}
defer {
needsRerender = false
layoutSubviews()
}
subviews.forEach { $0.removeFromSuperview() }
let views = wrapper?.profilePictures
.map { vm -> ProfilePictureView in
let view = ProfilePictureView()
view.setImage(for: vm)
view.layer.borderColor = UIColor.white.cgColor
view.layer.borderWidth = 2
return view
}
_ = views?.reduce(nil) { prev, view -> ProfilePictureView in
self.insertSubview(view, at: 0)
view.snp.makeConstraints { make in
make.height.equalToSuperview()
make.width.equalTo(view.snp.height)
guard view != views?.first, let prev = prev else {
make.left.equalToSuperview()
return
}
make.left.equalTo(prev.snp.right).inset(frame.height * 0.55)
}
return view
}
}
override func layoutSubviews() {
super.layoutSubviews()
guard !needsRerender else {
updateImageLayout()
return
}
let minX = subviews.reduce(0) { acc, v in min(acc, v.frame.minX) }
let maxX = subviews.reduce(0) { acc, v in max(acc, v.frame.maxX) }
let width = max(ceil(maxX - minX), preferredSize.width)
preferredSize = CGSize(
width: width,
height: frame.height
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment