// // GridCollectionViewCell.swift // Hthik // // Created by Hthik on 10/21/15. // Copyright © 2015 Hthik. All rights reserved. // import UIKit class GridCollectionViewCell: UICollectionViewCell { let imageView = UIImageView() let textLabel = UILabel() let bottomImageView = UIImageView(image: UIImage(named: "zw")) var isImageViewVibrancyEnabled = true { didSet { if self.isImageViewVibrancyEnabled { self.vibrancyView.contentView.addSubview(self.bottomImageView) // self.vibrancyView.contentView.addSubview(self.imageView) bottomImageView.addSubview(imageView) } else { self.contentView.addSubview(self.bottomImageView) // self.contentView.addSubview(self.imageView) bottomImageView.addSubview(imageView) } } } var isTextLabelVibrancyEnabled = true { didSet { if self.isTextLabelVibrancyEnabled { self.vibrancyView.contentView.addSubview(self.textLabel) } else { self.contentView.addSubview(self.textLabel) } } } var maximumImageSize: CGSize = CGSize(width: 160, height: 130) { didSet { self.updateMaximumImageSize() } } private var vibrancyView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .dark))) private var imageViewWidthConstraint: NSLayoutConstraint! private var imageViewHeightConstraint: NSLayoutConstraint! private var bottomimageViewWidthConstraint: NSLayoutConstraint! private var bottomimageViewHeightConstraint: NSLayoutConstraint! private var textLabelBottomAnchorConstraint: NSLayoutConstraint! private var textLabelVerticalSpacingConstraint: NSLayoutConstraint! private var textLabelFocusedVerticalSpacingConstraint: NSLayoutConstraint? override init(frame: CGRect) { super.init(frame: frame) self.configureSubviews() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) self.configureSubviews() } let imgHeight = 80.0 let imgWidth = 113.0 private func configureSubviews() { // Fix super annoying Unsatisfiable Constraints message in debugger by setting autoresizingMask self.contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight] self.clipsToBounds = false self.contentView.clipsToBounds = false self.vibrancyView.translatesAutoresizingMaskIntoConstraints = false self.vibrancyView.contentView.translatesAutoresizingMaskIntoConstraints = false self.contentView.addSubview(self.vibrancyView) imageView.layer.masksToBounds = true imageView.layer.cornerRadius = 6 self.imageView.contentMode = .scaleAspectFill self.bottomImageView.contentMode = .scaleAspectFit #if os(tvOS) self.imageView.adjustsImageWhenAncestorFocused = true #endif // self.contentView.addSubview(self.imageView) self.contentView.addSubview(self.bottomImageView) bottomImageView.addSubview(imageView) self.textLabel.font = UIFont.boldSystemFont(ofSize: 12) self.textLabel.textAlignment = .center self.textLabel.numberOfLines = 0 self.contentView.addSubview(self.textLabel) /* Auto Layout */ // Vibrancy View // Need to add explicit constraints for vibrancyView + vibrancyView.contentView or else Auto Layout won't calculate correct size 🙄 self.vibrancyView.topAnchor.constraint(equalTo: self.contentView.topAnchor).isActive = true self.vibrancyView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor).isActive = true self.vibrancyView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor).isActive = true self.vibrancyView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor).isActive = true self.vibrancyView.contentView.topAnchor.constraint(equalTo: self.vibrancyView.topAnchor).isActive = true self.vibrancyView.contentView.bottomAnchor.constraint(equalTo: self.vibrancyView.bottomAnchor).isActive = true self.vibrancyView.contentView.leadingAnchor.constraint(equalTo: self.vibrancyView.leadingAnchor).isActive = true self.vibrancyView.contentView.trailingAnchor.constraint(equalTo: self.vibrancyView.trailingAnchor).isActive = true // Image View self.imageView.translatesAutoresizingMaskIntoConstraints = false self.imageView.topAnchor.constraint(equalTo: self.vibrancyView.topAnchor,constant: 29).isActive = true self.imageView.centerXAnchor.constraint(equalTo: self.vibrancyView.centerXAnchor).isActive = true self.bottomImageView.translatesAutoresizingMaskIntoConstraints = false self.bottomImageView.topAnchor.constraint(equalTo: self.vibrancyView.topAnchor).isActive = true self.bottomImageView.centerXAnchor.constraint(equalTo: self.vibrancyView.centerXAnchor).isActive = true self.imageViewWidthConstraint = self.imageView.widthAnchor.constraint(equalToConstant: imgWidth) self.imageViewWidthConstraint.isActive = true self.imageViewHeightConstraint = self.imageView.heightAnchor.constraint(equalToConstant: imgHeight) self.imageViewHeightConstraint.priority = UILayoutPriority(999) // Fixes "Unable to simultaneously satisfy constraints" runtime error when inserting new grid row. self.imageViewHeightConstraint.isActive = true self.bottomimageViewWidthConstraint = self.bottomImageView.widthAnchor.constraint(equalToConstant: 160) self.bottomimageViewWidthConstraint.isActive = true self.bottomimageViewHeightConstraint = self.bottomImageView.heightAnchor.constraint(equalToConstant: 130) self.bottomimageViewHeightConstraint.priority = UILayoutPriority(999) // Fixes "Unable to simultaneously satisfy constraints" runtime error when inserting new grid row. self.bottomimageViewHeightConstraint.isActive = true // Text Label self.textLabel.translatesAutoresizingMaskIntoConstraints = false self.textLabel.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor).isActive = true self.textLabel.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor).isActive = true self.textLabelBottomAnchorConstraint = self.textLabel.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor,constant: -10) self.textLabelBottomAnchorConstraint.isActive = true self.textLabelVerticalSpacingConstraint = self.textLabel.topAnchor.constraint(equalTo: self.bottomImageView.bottomAnchor) self.textLabelVerticalSpacingConstraint.isActive = true #if os(tvOS) self.textLabelVerticalSpacingConstraint.active = false self.textLabelFocusedVerticalSpacingConstraint = self.textLabel.topAnchor.constraintEqualToAnchor(self.bottomImageView.focusedFrameGuide.bottomAnchor, constant: 0) self.textLabelFocusedVerticalSpacingConstraint?.active = true #else self.textLabelVerticalSpacingConstraint.isActive = true #endif self.updateMaximumImageSize() } override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) { super.didUpdateFocus(in: context, with: coordinator) coordinator.addCoordinatedAnimations({ if context.nextFocusedView == self { self.textLabelBottomAnchorConstraint?.isActive = false self.textLabelVerticalSpacingConstraint.isActive = false self.textLabelFocusedVerticalSpacingConstraint?.isActive = true self.textLabel.textColor = UIColor.white } else { self.textLabelFocusedVerticalSpacingConstraint?.isActive = false self.textLabelBottomAnchorConstraint?.isActive = true self.textLabelVerticalSpacingConstraint.isActive = true self.textLabel.textColor = UIColor.black } self.layoutIfNeeded() }, completion: nil) } } private extension GridCollectionViewCell { func updateMaximumImageSize() { self.imageViewWidthConstraint.constant = imgWidth self.imageViewHeightConstraint.constant = imgHeight // textLabel.backgroundColor = .red self.textLabelVerticalSpacingConstraint.constant = 0 self.textLabelFocusedVerticalSpacingConstraint?.constant = self.maximumImageSize.height / 10.0 // 修改 textLabel 的固定高度为 30 // let textLabelFixedHeight: CGFloat = 30 // // self.textLabelVerticalSpacingConstraint.constant = textLabelFixedHeight // self.textLabelFocusedVerticalSpacingConstraint?.constant = textLabelFixedHeight / 50 } }