gpt4 book ai didi

ios - 如何复制 iOS 1 0's Apple Music "Peek 和弹出操作菜单”

转载 作者:IT王子 更新时间:2023-10-29 05:37:42 25 4
gpt4 key购买 nike

iOS 10 有一项我想复制的功能。当您在 Apple Music 应用程序中对专辑进行 3D 触摸时,它会打开如下所示的菜单。然而,与正常的 peek 和 pop 不同的是,它不会在您抬起手指时消失。我该如何复制它?

enter image description here

最佳答案

我最接近复制它的是以下代码。它创建了音乐应用程序的虚拟副本。然后我添加了 PeekPop-3D-Touch 委托(delegate)。

但是,在委托(delegate)中,我向手势识别器添加了一个观察器,然后在查看时取消手势,但在抬起手指时重新启用它。为了重新启用它,我做了异步操作,因为预览会在没有异步调度的情况下立即消失。我找不到解决方法..

现在如果你点击蓝色框外,它会像正常一样消失 =]

http://i.imgur.com/073M2Ku.jpg http://i.imgur.com/XkwUBly.jpg

enter image description here enter image description here

//
// ViewController.swift
// PeekPopExample
//
// Created by Brandon Anthony on 2016-07-16.
// Copyright © 2016 XIO. All rights reserved.
//

import UIKit


class MusicViewController: UITabBarController, UITabBarControllerDelegate {

var tableView: UITableView!
var collectionView: UICollectionView!

override func viewDidLoad() {
super.viewDidLoad()

self.initControllers()
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

func initControllers() {
let libraryController = LibraryViewController()
let forYouController = UIViewController()
let browseController = UIViewController()
let radioController = UIViewController()
let searchController = UIViewController()

libraryController.title = "Library"
libraryController.tabBarItem.image = nil

forYouController.title = "For You"
forYouController.tabBarItem.image = nil

browseController.title = "Browse"
browseController.tabBarItem.image = nil

radioController.title = "Radio"
radioController.tabBarItem.image = nil

searchController.title = "Search"
searchController.tabBarItem.image = nil

self.viewControllers = [libraryController, forYouController, browseController, radioController, searchController];
}


}

以及 ForceTouch 暂停的实现..

//
// LibraryViewController.swift
// PeekPopExample
//
// Created by Brandon Anthony on 2016-07-16.
// Copyright © 2016 XIO. All rights reserved.
//

import Foundation
import UIKit


//Views and Cells..

class AlbumView : UIView {
var albumCover: UIImageView!
var title: UILabel!
var artist: UILabel!

override init(frame: CGRect) {
super.init(frame: frame)

self.initControls()
self.setTheme()
self.doLayout()
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func initControls() {
self.albumCover = UIImageView()
self.title = UILabel()
self.artist = UILabel()
}

func setTheme() {
self.albumCover.contentMode = .scaleAspectFit
self.albumCover.layer.cornerRadius = 5.0
self.albumCover.backgroundColor = UIColor.lightGray()

self.title.text = "Unknown"
self.title.font = UIFont.systemFont(ofSize: 12)

self.artist.text = "Unknown"
self.artist.textColor = UIColor.lightGray()
self.artist.font = UIFont.systemFont(ofSize: 12)
}

func doLayout() {
self.addSubview(self.albumCover)
self.addSubview(self.title)
self.addSubview(self.artist)

let views = ["albumCover": self.albumCover, "title": self.title, "artist": self.artist];
var constraints = Array<String>()

constraints.append("H:|-0-[albumCover]-0-|")
constraints.append("H:|-0-[title]-0-|")
constraints.append("H:|-0-[artist]-0-|")
constraints.append("V:|-0-[albumCover]-[title]-[artist]-0-|")

let aspectRatioConstraint = NSLayoutConstraint(item: self.albumCover, attribute: .width, relatedBy: .equal, toItem: self.albumCover, attribute: .height, multiplier: 1.0, constant: 0.0)

self.addConstraint(aspectRatioConstraint)

for constraint in constraints {
self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: constraint, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
}

for view in self.subviews {
view.translatesAutoresizingMaskIntoConstraints = false
}
}
}

class AlbumCell : UITableViewCell {
var firstAlbumView: AlbumView!
var secondAlbumView: AlbumView!

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)

self.initControls()
self.setTheme()
self.doLayout()
}

required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

func initControls() {
self.firstAlbumView = AlbumView(frame: CGRect.zero)
self.secondAlbumView = AlbumView(frame: CGRect.zero)
}

func setTheme() {

}

func doLayout() {
self.contentView.addSubview(self.firstAlbumView)
self.contentView.addSubview(self.secondAlbumView)

let views: [String: AnyObject] = ["firstAlbumView": self.firstAlbumView, "secondAlbumView": self.secondAlbumView];
var constraints = Array<String>()

constraints.append("H:|-15-[firstAlbumView(==secondAlbumView)]-15-[secondAlbumView(==firstAlbumView)]-15-|")
constraints.append("V:|-15-[firstAlbumView]-15-|")
constraints.append("V:|-15-[secondAlbumView]-15-|")

for constraint in constraints {
self.contentView.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: constraint, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
}

for view in self.contentView.subviews {
view.translatesAutoresizingMaskIntoConstraints = false
}
}
}



//Details..

class DetailSongViewController : UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

self.view.backgroundColor = UIColor.blue()
}

/*override func previewActionItems() -> [UIPreviewActionItem] {
let regularAction = UIPreviewAction(title: "Regular", style: .default) { (action: UIPreviewAction, vc: UIViewController) -> Void in

}

let destructiveAction = UIPreviewAction(title: "Destructive", style: .destructive) { (action: UIPreviewAction, vc: UIViewController) -> Void in

}

let actionGroup = UIPreviewActionGroup(title: "Group...", style: .default, actions: [regularAction, destructiveAction])

return [actionGroup]
}*/
}











//Implementation..

extension LibraryViewController : UIViewControllerPreviewingDelegate {
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {

guard let indexPath = self.tableView.indexPathForRow(at: location) else {
return nil
}

guard let cell = self.tableView.cellForRow(at: indexPath) else {
return nil
}


previewingContext.previewingGestureRecognizerForFailureRelationship.addObserver(self, forKeyPath: "state", options: .new, context: nil)


let detailViewController = DetailSongViewController()
detailViewController.preferredContentSize = CGSize(width: 0.0, height: 300.0)
previewingContext.sourceRect = cell.frame
return detailViewController
}

func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {

//self.show(viewControllerToCommit, sender: self)
}

override func observeValue(forKeyPath keyPath: String?, of object: AnyObject?, change: [NSKeyValueChangeKey : AnyObject]?, context: UnsafeMutablePointer<Void>?) {
if let object = object {
if keyPath == "state" {
let newValue = change![NSKeyValueChangeKey.newKey]!.integerValue
let state = UIGestureRecognizerState(rawValue: newValue!)!
switch state {
case .began, .changed:
self.navigationItem.title = "Peeking"
(object as! UIGestureRecognizer).isEnabled = false

case .ended, .failed, .cancelled:
self.navigationItem.title = "Not committed"
object.removeObserver(self, forKeyPath: "state")

DispatchQueue.main.async(execute: {
(object as! UIGestureRecognizer).isEnabled = true
})


case .possible:
break
}
}
}
}
}


class LibraryViewController : UIViewController, UITableViewDelegate, UITableViewDataSource {

var tableView: UITableView!

override func viewDidLoad() {
super.viewDidLoad()

self.initControls()
self.setTheme()
self.registerClasses()
self.registerPeekPopPreviews();
self.doLayout()
}

func initControls() {
self.tableView = UITableView(frame: CGRect.zero, style: .grouped)
}

func setTheme() {
self.edgesForExtendedLayout = UIRectEdge()
self.tableView.dataSource = self;
self.tableView.delegate = self;
}

func registerClasses() {
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Default")
self.tableView.register(AlbumCell.self, forCellReuseIdentifier: "AlbumCell")
}

func registerPeekPopPreviews() {
//if (self.traitCollection.forceTouchCapability == .available) {
self.registerForPreviewing(with: self, sourceView: self.tableView)
//}
}

func doLayout() {
self.view.addSubview(self.tableView)

let views: [String: AnyObject] = ["tableView": self.tableView];
var constraints = Array<String>()

constraints.append("H:|-0-[tableView]-0-|")
constraints.append("V:|-0-[tableView]-0-|")

for constraint in constraints {
self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: constraint, options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: views))
}

for view in self.view.subviews {
view.translatesAutoresizingMaskIntoConstraints = false
}
}



func numberOfSections(in tableView: UITableView) -> Int {
return 2
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return section == 0 ? 5 : 10
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return (indexPath as NSIndexPath).section == 0 ? 44.0 : 235.0
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return section == 0 ? 75.0 : 50.0
}

func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 0.0001
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return section == 0 ? "Library" : "Recently Added"
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

if (indexPath as NSIndexPath).section == 0 { //Library
let cell = tableView.dequeueReusableCell(withIdentifier: "Default", for: indexPath)

switch (indexPath as NSIndexPath).row {
case 0:
cell.accessoryType = .disclosureIndicator
cell.textLabel?.text = "Playlists"

case 1:
cell.accessoryType = .disclosureIndicator
cell.textLabel?.text = "Artists"

case 2:
cell.accessoryType = .disclosureIndicator
cell.textLabel?.text = "Albums"

case 3:
cell.accessoryType = .disclosureIndicator
cell.textLabel?.text = "Songs"

case 4:
cell.accessoryType = .disclosureIndicator
cell.textLabel?.text = "Downloads"


default:
break
}
}

if (indexPath as NSIndexPath).section == 1 { //Recently Added
let cell = tableView.dequeueReusableCell(withIdentifier: "AlbumCell", for: indexPath)
cell.selectionStyle = .none
return cell
}

return tableView.dequeueReusableCell(withIdentifier: "Default", for: indexPath)
}
}

关于ios - 如何复制 iOS 1 0's Apple Music "Peek 和弹出操作菜单”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38416862/

25 4 0