// // AttachmentsContainerView.swift // Tusker // // Created by Shadowfacts on 6/16/19. // Copyright © 2019 Shadowfacts. All rights reserved. // import UIKit import Pachyderm class AttachmentsContainerView: UIView { var delegate: AttachmentViewDelegate? let attachmentViews: NSHashTable = .weakObjects() override func awakeFromNib() { super.awakeFromNib() self.isUserInteractionEnabled = true } func getAttachmentView(for attachment: Attachment) -> AttachmentView? { return attachmentViews.allObjects.first { $0.attachment.id == attachment.id } } // MARK: - User Interaface func updateUI(status: Status) { let attachments = status.attachments.filter { $0.kind == .image } attachmentViews.removeAllObjects() subviews.forEach { $0.removeFromSuperview() } if attachments.count > 0 { self.isHidden = false switch attachments.count { case 1: makeMainView(createAttachmentView(attachments[0])) case 2: let left = createAttachmentView(attachments[0]) makeMainView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [ left, createAttachmentView(attachments[1]) ])) NSLayoutConstraint.activate([ left.halfWidth() ]) case 3: let left = createAttachmentView(attachments[0]) let topRight = createAttachmentView(attachments[1]) makeMainView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [ left, createAttachmentsStack(axis: .vertical, arrangedSubviews: [ topRight, createAttachmentView(attachments[2]) ]) ])) NSLayoutConstraint.activate([ left.halfWidth(), topRight.halfHeight(), ]) case 4: let topLeft = createAttachmentView(attachments[0]) let left = createAttachmentsStack(axis: .vertical, arrangedSubviews: [ topLeft, createAttachmentView(attachments[2]) ]) let topRight = createAttachmentView(attachments[1]) makeMainView(createAttachmentsStack(axis: .horizontal, arrangedSubviews: [ left, createAttachmentsStack(axis: .vertical, arrangedSubviews: [ topRight, createAttachmentView(attachments[3]) ]) ])) NSLayoutConstraint.activate([ left.halfWidth(), topLeft.halfHeight(), topRight.halfHeight(), ]) default: fatalError("Too many attachments") } } else { self.isHidden = true } } private func createAttachmentView(_ attachment: Attachment) -> AttachmentView { let attachmentView = AttachmentView(attachment: attachment) attachmentView.delegate = delegate attachmentView.translatesAutoresizingMaskIntoConstraints = false attachmentViews.add(attachmentView) return attachmentView } private func createAttachmentsStack(axis: NSLayoutConstraint.Axis, arrangedSubviews: [UIView]) -> UIStackView { let stack = UIStackView(arrangedSubviews: arrangedSubviews) stack.axis = axis stack.spacing = 4 stack.translatesAutoresizingMaskIntoConstraints = false return stack } private func makeMainView(_ view: UIView) { addSubview(view) NSLayoutConstraint.activate([ view.leadingAnchor.constraint(equalTo: leadingAnchor), view.trailingAnchor.constraint(equalTo: trailingAnchor), view.topAnchor.constraint(equalTo: topAnchor), view.bottomAnchor.constraint(equalTo: bottomAnchor) ]) } } fileprivate extension UIView { enum RelativeSize { case full, half var multiplier: CGFloat { switch self { case .full: return 1 case .half: return 0.5 } } } func halfWidth(spacing: CGFloat = 4) -> NSLayoutConstraint { return widthAnchor.constraint(equalTo: superview!.widthAnchor, multiplier: 0.5, constant: -spacing / 2) } func halfHeight(spacing: CGFloat = 4) -> NSLayoutConstraint { return heightAnchor.constraint(equalTo: superview!.heightAnchor, multiplier: 0.5, constant: -spacing / 2) } }