Skip to content
This repository has been archived by the owner on Jun 21, 2020. It is now read-only.

Commit

Permalink
[widget,notification-content] i hate this
Browse files Browse the repository at this point in the history
  • Loading branch information
kirb committed Jul 4, 2017
1 parent f2c8f63 commit e77bc3a
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 150 deletions.
206 changes: 59 additions & 147 deletions global/MediaControlsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,22 @@ class MediaControlsViewController: UIViewController, MPUNowPlayingDelegate {
case notification
}

// we need to keep strong references around to these, otherwise they’d be released by ARC and we
// we need to keep strong references to these around, otherwise they’d be released by ARC and we
// don’t get to have the goodness they provide
var nowPlayingController: MPUNowPlayingController!
var controlsViewController: HaxMediaControlsViewController!

var containerView: UIView!
var artworkView: MPUNowPlayingArtworkView!
var labelsContainerView: UIView!

var appNameLabel: UILabel!
var titleLabel: MPUControlCenterMetadataView!
var albumLabel: MPUControlCenterMetadataView!
var artistLabel: MPUControlCenterMetadataView!
var artistAlbumLabel: MPUControlCenterMetadataView!
var transportControls: UIView!

var extrasView: UIView!
var timeView: UIView!
var extrasSpacerView: UIView!

var appNameLabelHeightConstraint: NSLayoutConstraint!
var titleLabelHeightConstraint: NSLayoutConstraint!
var albumLabelHeightConstraint: NSLayoutConstraint!
var artistLabelHeightConstraint: NSLayoutConstraint!
var artistAlbumLabelHeightConstraint: NSLayoutConstraint!

var containerHeightConstraint: NSLayoutConstraint!
//var expandedTopConstraint: NSLayoutConstraint!
//var collapsedBottomConstraint: NSLayoutConstraint!

var state = InterfaceState.notification {
didSet {
view.setNeedsLayout()
Expand Down Expand Up @@ -69,102 +56,57 @@ class MediaControlsViewController: UIViewController, MPUNowPlayingDelegate {
let controlsView = controlsViewController.view!

// construct the views
let containerView = UIView()
containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(containerView)

artworkView = MPUNowPlayingArtworkView()
artworkView.activated = true
artworkView.translatesAutoresizingMaskIntoConstraints = false
artworkView.activated = true
containerView.addSubview(artworkView)

labelsContainerView = UIView()
labelsContainerView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(labelsContainerView)

// steal the transport controls from MPUControlCenterMediaControlsViewController, which will
// manage them for us
transportControls = controlsView.transportControls
transportControls.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(transportControls)

appNameLabel = UILabel()
appNameLabel.translatesAutoresizingMaskIntoConstraints = false
appNameLabel.font = UIFont.systemFont(ofSize: 15)
appNameLabel.textColor = UIColor(white: 0.9, alpha: 1)
labelsContainerView.addSubview(appNameLabel)

// also steal the labels
titleLabel = controlsView.value(forKey: "_titleLabel") as! MPUControlCenterMetadataView
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.numberOfLines = 1
titleLabel.marqueeEnabled = true
titleLabel.isUserInteractionEnabled = false
labelsContainerView.addSubview(titleLabel)

albumLabel = controlsView.value(forKey: "_albumLabel") as! MPUControlCenterMetadataView
albumLabel.translatesAutoresizingMaskIntoConstraints = false
albumLabel.marqueeEnabled = true
labelsContainerView.addSubview(albumLabel)

artistLabel = controlsView.value(forKey: "_artistLabel") as! MPUControlCenterMetadataView
artistLabel.translatesAutoresizingMaskIntoConstraints = false
artistLabel.marqueeEnabled = true
labelsContainerView.addSubview(artistLabel)

artistAlbumLabel = controlsView.value(forKey: "_artistAlbumConcatenatedLabel") as! MPUControlCenterMetadataView
artistAlbumLabel.translatesAutoresizingMaskIntoConstraints = false
artistAlbumLabel.numberOfLines = 1
artistAlbumLabel.marqueeEnabled = true
artistAlbumLabel.isUserInteractionEnabled = false
labelsContainerView.addSubview(artistAlbumLabel)

appNameLabelHeightConstraint = NSLayoutConstraint(item: appNameLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 0)
titleLabelHeightConstraint = NSLayoutConstraint(item: titleLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 0)
albumLabelHeightConstraint = NSLayoutConstraint(item: albumLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 0)
artistLabelHeightConstraint = NSLayoutConstraint(item: artistLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 0)
artistAlbumLabelHeightConstraint = NSLayoutConstraint(item: artistAlbumLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 0)

labelsContainerView.addConstraints([
titleLabelHeightConstraint,
albumLabelHeightConstraint,
artistLabelHeightConstraint,
artistAlbumLabelHeightConstraint
])
// steal the transport controls from MPUControlCenterMediaControlsViewController, which will
// manage them for us
transportControls = controlsView.transportControls
transportControls.translatesAutoresizingMaskIntoConstraints = false
labelsContainerView.addSubview(transportControls)

// sean spacer (and our prime minister, mr trumble)
let spacerView = UIView()
spacerView.translatesAutoresizingMaskIntoConstraints = false
labelsContainerView.addSubview(spacerView)

// views within the widget expanded area
if isWidget {
containerHeightConstraint = NSLayoutConstraint(item: containerView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 0)
view.addConstraint(containerHeightConstraint)
}

extrasView = UIView()
extrasView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(extrasView)

timeView = controlsView.value(forKey: "_timeView") as! UIView
timeView.translatesAutoresizingMaskIntoConstraints = false
extrasView.addSubview(timeView)

extrasSpacerView = UIView()
extrasSpacerView.translatesAutoresizingMaskIntoConstraints = false
extrasView.addSubview(extrasSpacerView)

// do that auto layout stuff
let margin: CGFloat = isWidget ? 11 : 14
let widgetHeight: CGFloat = 95
let margin: CGFloat = isWidget ? 6 : 12
let artworkInset: CGFloat = isWidget ? 4 : 2

let metrics: [String: NSNumber] = [
"heightFactor": 0.4,
"widgetHeight": 95,
"widgetHeight": widgetHeight as NSNumber,
"widgetArtworkSize": (widgetHeight - (margin + artworkInset) * 2) as NSNumber,

"margin": margin as NSNumber,
"doubleMargin": (margin * 2 as CGFloat) as NSNumber, // swift...
"labelsContainerLeading": isWidget ? (margin - 4) as NSNumber : margin as NSNumber,
"labelsContainerTrailing": isWidget ? (margin - 6) as NSNumber : margin as NSNumber,
"labelsContainerTopOutset": isWidget ? -3 : 0,
"labelsContainerBottomOutset": isWidget ? -6 : 0,

"labelSpacing": 4,
"artworkInset": artworkInset as NSNumber,
"innerMargin": isWidget ? 6 : 8,

"controlsWidth": 160,
"controlsHeight": isWidget ? 38 : 44
Expand All @@ -176,60 +118,56 @@ class MediaControlsViewController: UIViewController, MPUNowPlayingDelegate {

"artworkView": artworkView,
"labelsContainerView": labelsContainerView,
"transportControls": transportControls,

"appNameLabel": appNameLabel,

"titleLabel": titleLabel,
"albumLabel": albumLabel,
"artistLabel": artistLabel,
"artistAlbumLabel": artistAlbumLabel,
"spacerView": spacerView
"spacerView": spacerView,
"transportControls": transportControls
]

view.hb_addCompactConstraints([
"containerView.top = self.top + margin",
"containerView.leading = self.leading + margin",
"containerView.trailing = self.trailing - margin",

isWidget
? "containerView.height = widgetHeight - doubleMargin"
: "containerView.bottom = self.bottom - margin"
"containerView.trailing = self.trailing - margin"
], metrics: metrics, views: views)

containerView.hb_addCompactConstraints([
"artworkView.top = containerView.top + artworkInset",
"artworkView.width = artworkView.height"
], metrics: metrics, views: views)

if !isWidget {
view.hb_addCompactConstraints([
"self.height = self.width * heightFactor"
view.hb_addCompactConstraint("containerView.bottom = self.bottom - margin", metrics: metrics, views: views)

containerView.hb_addCompactConstraints([
"artworkView.bottom = containerView.bottom - artworkInset"
"labelsContainerView.top = containerView.top",
"labelsContainerView.bottom = containerView.bottom"
], metrics: metrics, views: views)
}

containerView.hb_addCompactConstraints([
"artworkView.top = self.top",
"artworkView.leading = self.leading",
"artworkView.bottom = self.bottom",
"artworkView.width = self.height",

"labelsContainerView.top = self.top + labelsContainerTopOutset",
"labelsContainerView.leading = artworkView.trailing + labelsContainerLeading",
"labelsContainerView.trailing = self.trailing + labelsContainerTrailing",

"transportControls.top = labelsContainerView.bottom",
"transportControls.bottom = self.bottom - labelsContainerBottomOutset",
"transportControls.width = controlsWidth",
"transportControls.height = controlsHeight",
"transportControls.centerX = labelsContainerView.centerX"
], metrics: metrics, views: views)
containerView.hb_addConstraints(withVisualFormat: "H:|-artworkInset-[artworkView\(isWidget ? "(==widgetArtworkSize)" : "")]-innerMargin-[labelsContainerView]|", options: NSLayoutFormatOptions(), metrics: metrics, views: views)

// is there not a better, concise way to do this??
labelsContainerView.hb_addCompactConstraints([
"appNameLabel.leading = self.leading", "appNameLabel.trailing = self.trailing",
"titleLabel.leading = self.leading", "titleLabel.trailing = self.trailing",
"albumLabel.leading = self.leading", "albumLabel.trailing = self.trailing",
"artistLabel.leading = self.leading", "artistLabel.trailing = self.trailing",
"artistAlbumLabel.leading = self.leading", "artistAlbumLabel.trailing = self.trailing",
"spacerView.leading = self.leading", "spacerView.trailing = self.trailing",

"transportControls.width = controlsWidth",
"transportControls.centerX = labelsContainerView.centerX"
], metrics: metrics, views: views)

labelsContainerView.hb_addConstraints(withVisualFormat: "V:|[appNameLabel][titleLabel][albumLabel][artistLabel][artistAlbumLabel][spacerView]|", options: NSLayoutFormatOptions(), metrics: metrics, views: views)
labelsContainerView.hb_addConstraints(withVisualFormat: "V:|[titleLabel][artistAlbumLabel][spacerView][transportControls(controlsHeight)]|", options: NSLayoutFormatOptions(), metrics: metrics, views: views)

// manually make some constraints for the label heights
titleLabelHeightConstraint = NSLayoutConstraint(item: titleLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 0)
artistAlbumLabelHeightConstraint = NSLayoutConstraint(item: artistAlbumLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 0)

labelsContainerView.addConstraints([
titleLabelHeightConstraint,
artistAlbumLabelHeightConstraint
])

// set up the now playing controller to send us updates
nowPlayingController = MPUNowPlayingController()
Expand All @@ -244,56 +182,30 @@ class MediaControlsViewController: UIViewController, MPUNowPlayingDelegate {

super.viewWillLayoutSubviews()

// numberOfLines and marqueeEnabled can be changed behind our backs (i should really just
// construct these labels myself... not enough time now) so set them again here
titleLabel.numberOfLines = isSmall ? 1 : 2
titleLabel.marqueeEnabled = isSmall

albumLabel.isHidden = isSmall
artistLabel.isHidden = isSmall
artistAlbumLabel.isHidden = !isSmall
extrasView.isHidden = isSmall

artistAlbumLabel.marqueeEnabled = true
artistAlbumLabel.numberOfLines = isSmall ? 1 : 2

switch state {
case .widgetCollapsed:
containerHeightConstraint.constant = 95
break

case .widgetExpanded:
containerHeightConstraint.constant = 140
break

case .notification:
break
}
// if titleLabel isn't 1 line, this won't do anything but will still align it with the others
titleLabel.marqueeEnabled = isSmall
artistAlbumLabel.marqueeEnabled = isSmall

artistAlbumLabel.isHidden = false

let labelExtraMargin: CGFloat = 2

// the fuck is a greatestFiniteMagnitude? why wasn’t calling it “max”, like, you know, the
// maximum number possible for the type, good enough?
let size = CGSize(width: labelsContainerView.frame.size.width, height: CGFloat.greatestFiniteMagnitude)
appNameLabelHeightConstraint.constant = isSmall ? 0 : appNameLabel.sizeThatFits(size).height + labelExtraMargin
titleLabelHeightConstraint.constant = titleLabel.sizeThatFits(size).height + labelExtraMargin
albumLabelHeightConstraint.constant = isSmall ? 0 : albumLabel.sizeThatFits(size).height + labelExtraMargin
artistLabelHeightConstraint.constant = isSmall ? 0 : artistLabel.sizeThatFits(size).height + labelExtraMargin
artistAlbumLabelHeightConstraint.constant = isSmall ? artistAlbumLabel.sizeThatFits(size).height + labelExtraMargin : 0
artistAlbumLabelHeightConstraint.constant = artistAlbumLabel.sizeThatFits(size).height + labelExtraMargin
}

// MARK: - Now playing

func nowPlayingController(_ nowPlayingController: MPUNowPlayingController!, nowPlayingInfoDidChange info: [AnyHashable: Any]!) {
artworkView.artworkImage = nowPlayingController.currentNowPlayingArtwork

if appNameLabel != nil {
if nowPlayingController.nowPlayingAppDisplayID == nil {
appNameLabel.text = ""
} else {
if let app = LSApplicationProxy(forIdentifier: nowPlayingController.nowPlayingAppDisplayID) {
appNameLabel.text = app.localizedName.localizedUppercase
}
}
}

view.setNeedsLayout()
}

Expand Down
10 changes: 10 additions & 0 deletions notification-content/NotificationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ class NotificationViewController: MediaControlsViewController, UNNotificationCon
fatalError("")
}

// MARK: - View controller

override func loadView() {
super.loadView()

// ensure the view is the same height as we defined in the Info.plist, so we don't get ugly
// window resizing between when the window opens and when the content is fully loaded
view.hb_addCompactConstraint("self.height = self.width * heightFactor", metrics: [ "heightFactor": 0.4 ], views: nil)
}

// MARK: - Notification content

func didReceive(_ notification: UNNotification) {
Expand Down
Loading

0 comments on commit e77bc3a

Please sign in to comment.