26、iOS应用功能增强:3D Touch、设置与图像滤镜

iOS应用功能增强:3D Touch、设置与图像滤镜

1. 3D Touch功能介绍

在iPhone 6S、6S Plus或任何iPhone 7机型上,可利用3D Touch功能,在SFSafariViewController中通过用力按压链接来快速预览链接内容。部分iOS设备能够检测并利用用户触摸屏幕时施加的压力,以提供对应用功能的快速访问,主要有以下两种使用方式:

1.1 主屏幕快速操作(Home Screen Quick Actions)

主屏幕快速操作是指用户用力按压应用图标时出现的菜单项,可让应用在后台快速执行操作或直接跳转到应用中的常用目标。主屏幕快速操作分为静态和动态两种:
- 静态操作 :不会改变,通过在应用的Info.plist中添加名为UIApplicationShortcutItems的数组来设置,数组中的每个字典包含以下项目:
| 项目 | 是否必需 | 说明 |
| ---- | ---- | ---- |
| UIApplicationShortcutItemType | 是 | 应用将接收的字符串 |
| UIApplicationShortcutItemTitle | 是 | 用户将看到的标签 |
| UIApplicationShortcutItemSubtitle | 否 | 用户将在标题下方看到的标签 |
| UIApplicationShortcutItemIconFile | 否 | 提供自己的文件 |
| UIApplicationShortcutIconType | 否 | 使用系统提供的图标 |
| UIApplicationShortcutItemUserInfo | 否 | 将传递给应用的字典 |
- 动态操作 :是UIApplicationShortcutItem对象的实例,应用的共享UIApplication对象有一个名为shortcutItems的数组,可控制该数组来添加快捷操作。

以下是添加一个静态操作以允许从主菜单创建新笔记的步骤:
1. 修改info.plist以支持创建笔记操作:
- 打开info.plist,插入一个新的键值对,键为UIApplicationShortcutItems,类型为数组。
- 将数组中的第一个且唯一的项目修改为字典。
- 在字典中添加一个新的键值对,键为UIApplicationShortcutItemTitle,值为字符串“New Note”。
- 添加另一个键值对,键为UIApplicationShortcutItemType,值为字符串“au.com.secretlab.Notes.new-note”,需将“au.com.secretlab.Notes”替换为应用的捆绑标识符。
- 最后,添加一个键值对,键为UIApplicationShortcutItemIconType,值为字符串“UIApplicationShortcutIconTypeCompose”。
2. 编写代码处理用户执行快速操作的情况:

// AppDelegate.swift
let createNoteActionType = "au.com.secretlab.Notes.new-note"

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Did we launch as a result of using a shortcut option?
    if let shortcutItem = launchOptions?[.shortcutItem] as? UIApplicationShortcutItem {
        // We did! Was it the 'create note' shortcut?
        if shortcutItem.type == createNoteActionType {
            // Create a new document.
            createNewDocument()
        }
        // Return false to indicate that 'performActionForShortcutItem'
        // doesn't need to be called
        return false
    }
    return true
}

func createNewDocument() {
    // Ensure that the root view controller is a navigation controller
    guard let navigationController = self.window?.rootViewController as? UINavigationController else {
        fatalError("The root view controller is not a navigationcontroller")
    }
    // Ensure that the navigation controller's root view controller is the
    // Document List
    guard let documentList = navigationController.viewControllers.first as? DocumentListViewController else {
        fatalError("first view controller isn't DocumentListViewController")
    }
    // Move back to the root view controller
    navigationController.popToRootViewController(animated: false)
    // Ask the document list to create a new document
    documentList.createDocument()
}

1.2 预览与弹出(Peek and Pop)

Peek and Pop功能允许用户通过用力按压屏幕上的元素来快速预览内容,若用户继续用力按压,内容将打开。以下是为应用添加Peek and Pop支持的步骤:
1. 在Storyboard中为DocumentViewController添加标识符:
- 打开main.storyboard,选择DocumentViewController。
- 打开检查器,转到身份检查器选项卡,在身份部分将DocumentViewController添加到Storyboard ID。
2. 注册文档列表视图控制器以支持Peek and Pop:

// DocumentListViewController.swift
override func viewDidLoad() {
    super.viewDidLoad()
    // Mark the collection view as preview-able, if our current device supports
    // 3D Touch.
    if self.traitCollection.forceTouchCapability == .available {
        self.registerForPreviewing(with: self, sourceView: self.collectionView!)
    }
}

extension DocumentListViewController : UIViewControllerPreviewingDelegate {
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
        // Determine which cell was tapped; if we can't
        // return nil to indicate that we can't offer a preview
        guard let indexPath = self.collectionView?.indexPathForItem(at: location) else {
            return nil
        }
        // Get the cell object for this location
        guard let cell = self.collectionView?.cellForItem(at: indexPath) else {
            fatalError("We have an index path, but not a cell")
        }
        // Determine the document URL that this cell represents
        let selectedItem = availableFiles[indexPath.item]
        // Tell the previewing context about
        // the shape that should remain unblurred
        previewingContext.sourceRect = cell.frame
        // Create a DocumentViewController for showing this file
        guard let documentVC = self.storyboard?.instantiateViewController(withIdentifier: "DocumentViewController") as? DocumentViewController else {
            fatalError("Expected to get a DocumentViewController here " +
                       "- make sure that the Document View Controller's" +
                       "storyboard identifier is set up correctly")
        }
        // Give the document URL to the document view controller
        documentVC.documentURL = selectedItem
        // Create a navigation controller to embed this in
        let navigationVC = UINavigationController(rootViewController: documentVC)
        // Return this navigation controller
        return navigationVC
    }

    func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
        // The viewControllerToCommit is a navigation controller
        // that contains a document view controller.
        // Ensure that this is the case.
        guard let navigationVC = viewControllerToCommit as? UINavigationController else {
            fatalError("Expected the preview view controller" +
                       "to be a navigation controller")
        }
        guard let documentVC = navigationVC.viewControllers.first as? DocumentViewController else {
            fatalError("View controller is not a document view controller")
        }
        // Get the document view controller's URL
        guard let url = documentVC.documentURL else {
            fatalError("Expected the document view controller" +
                       "to have a document set")
        }
        // Present the segue, just as if we'd tapped the cell
        self.performSegue(withIdentifier: "ShowDocument", sender: url)
    }
}

2. 设置功能添加

为应用添加一个设置项,用于控制文档打开时是否处于编辑状态。设置信息存储在UserDefaults类中,该类类似于一个持久化的大字典,即使应用退出也会保留数据。UserDefaults只能存储特定类型的对象,如字符串、数字、日期、数组、数据和字典,适用于存储非常小的信息。以下是添加设置项的步骤:
1. 创建设置包:
- 打开文件菜单,选择“New→File”。
- 添加一个新的“iOS→Resource→Settings Bundle”,命名为“Settings”并添加到Notes - iOS目标。
- 打开刚添加的Settings.bundle,打开其中的Root.plist文件。
- 移除偏好设置项列表中的所有项目。
- 选择偏好设置项并按Enter键创建一个新项。
- 将新项的类型设置为“Toggle Switch”。
- 将标题设置为“Documents are editable when opened.”。
- 将标识符设置为“document_edit_on_open”。
2. 让应用使用该偏好设置:

// DocumentViewController.swift
override func viewDidLoad() {
    super.viewDidLoad()
    self.isEditing = UserDefaults.standard.bool(forKey: "document_edit_on_open")
}

3. 撤销支持功能

为文本视图添加撤销更改的支持,利用内置的撤销管理器。以下是实现步骤:
1. 在DocumentViewController中添加属性:

// DocumentViewController.swift
var undoButton : UIBarButtonItem?
var didUndoObserver : AnyObject?
var didRedoObserver : AnyObject?
  1. 在viewDidLoad中注册撤销或重做更改的通知:
// DocumentViewController.swift
override func viewDidLoad() {
    super.viewDidLoad()
    let respondToUndoOrRedo = { (notification: Notification) -> Void in
        self.undoButton?.isEnabled = self.textView?.undoManager?.canUndo == true
    }
    didUndoObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.NSUndoManagerDidUndoChange, object: nil, queue: nil, using: respondToUndoOrRedo)
    didRedoObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.NSUndoManagerDidRedoChange, object: nil, queue: nil, using: respondToUndoOrRedo)
}
  1. 在updateBarItems中更改撤销按钮的启用状态:
// DocumentViewController.swift
func updateBarItems() {
    var rightButtonItems : [UIBarButtonItem] = []
    rightButtonItems.append(self.editButtonItem)
    if isEditing {
        undoButton = UIBarButtonItem(barButtonSystemItem: .undo, target: self.textView?.undoManager, action: #selector(UndoManager.undo))
        undoButton?.isEnabled = self.textView?.undoManager?.canUndo == true
        rightButtonItems.append(undoButton!)
    }
    // the button to segue to the attachment view controller
    let image = UIImage(named: "Position")
    let showButton = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(showLocation))
    // if there is already a location
    if self.document?.locationWrapper != nil {
        // we show the segue button
        rightButtonItems.append(showButton)
    } else {
        // if we don't have permission or permission is denied
        let status = CLLocationManager.authorizationStatus()
        if status == .denied || status == .restricted {
            // we don't have permission
            rightButtonItems.append(showButton)
        } else {
            // the activity indicator to show when determining location
            let spinner = UIActivityIndicatorView(activityIndicatorStyle: .gray)
            spinner.startAnimating()
            let spinItem = UIBarButtonItem(customView: spinner)
            rightButtonItems.append(spinItem)
        }
    }
    self.navigationItem.rightBarButtonItems = rightButtonItems
}
  1. 在textViewDidChange中更新撤销按钮状态:
// DocumentViewController.swift
func textViewDidChange(_ textView: UITextView) {
    self.undoButton?.isEnabled = self.textView.undoManager?.canUndo == true
    document?.text = textView.attributedText
    document?.updateChangeCount(.done)
}
  1. 在documentStateChanged方法中更新撤销按钮:
// DocumentViewController.swift
document.revert(toContentsOf: document.fileURL, completionHandler: { (success) -> Void in
    self.textView.attributedText = document.text
    self.attachmentsCollectionView?.reloadData()
    self.updateBarItems()
})
for version in conflictedVersions {
    version.isResolved = true
}

4. 图像滤镜功能添加

为应用添加用户对图像应用滤镜的功能,当用户查看图像时,屏幕底部将显示三个不同滤镜版本的图像按钮,点击按钮可将主图像视图更改为显示滤镜版本的图像。将使用Core Image框架来应用滤镜,该框架提供图像过滤、增强、编辑等有用的无损或基于管道的图像编辑功能。以下是实现步骤:
1. 在界面中添加UIView和按钮:
- 打开Main.storyboard,进入图像附件视图控制器。
- 添加一个UIView,使其填充屏幕宽度,高度为80点。
- 将其固定在底部和两侧。
- 将其背景颜色设置为黑色,透明度为0.5。
- 添加三个按钮,分别放置在左侧、中间和右侧,使其与包含它们的视图高度相同且为正方形。
- 将按钮的内容模式设置为“aspect fit”。
2. 在代码中实现滤镜功能:

// ImageAttachmentViewController.swift
@IBOutlet var filterButtons: [UIButton]!

@IBAction func showFilteredImage(_ sender: UIButton) {
    self.imageView?.image = sender.image(for: UIControlState())
    self.imageView?.contentMode = .scaleAspectFit
}

func prepareFilterPreviews() {
    let filters : [CIFilter?] = [
        CIFilter(name: "CIPhotoEffectChrome"),
        CIFilter(name: "CIPhotoEffectNoir"),
        CIFilter(name: "CIPhotoEffectInstant")
    ]
    guard let image = self.imageView?.image else {
        return
    }
    let context = CIContext(options: nil)
    for (number, filter) in filters.enumerated() {
        let button = filterButtons[number]
        let unprocessedImage = CIImage(image: image)
        filter?.setValue(unprocessedImage, forKey: kCIInputImageKey)
        if let processedCIImage = filter?.value(forKey: kCIOutputImageKey) as? CIImage {
            // Render the result into a CGImage
            let image = context.createCGImage(processedCIImage, from: CGRect(origin: CGPoint.zero, size: image.size))
            button.setImage(UIImage(cgImage: image!), for: UIControlState())
        }
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    // If we have data, and can make an image out of it...
    if let data = attachmentFile?.regularFileContents, let image = UIImage(data: data) {
        // Set the image
        self.imageView?.image = image
        prepareFilterPreviews()
    }
}

通过以上步骤,我们为iOS应用添加了3D Touch、设置、撤销和图像滤镜等功能,提升了应用的用户体验和实用性。

5. 各功能操作流程总结

为了更清晰地展示前面介绍的各项功能的操作步骤,下面以流程图和表格的形式进行总结。

5.1 主屏幕快速操作添加流程

graph LR
    A[修改info.plist] --> B[插入UIApplicationShortcutItems数组]
    B --> C[将数组首项设为字典]
    C --> D[添加UIApplicationShortcutItemTitle键值对]
    D --> E[添加UIApplicationShortcutItemType键值对]
    E --> F[添加UIApplicationShortcutItemIconType键值对]
    F --> G[编写AppDelegate.swift代码]
    G --> H[添加createNoteActionType属性]
    H --> I[在application didFinishLaunchingWithOptions中检查快捷操作]
    I --> J[编写createNewDocument函数]

5.2 各功能操作步骤对比

功能 操作步骤
主屏幕快速操作 1. 修改info.plist;2. 编写AppDelegate.swift代码
Peek and Pop 1. 在Storyboard中添加标识符;2. 注册文档列表视图控制器;3. 实现委托方法
设置功能 1. 创建设置包;2. 让应用使用偏好设置
撤销支持 1. 添加属性;2. 注册通知;3. 更新按钮状态
图像滤镜 1. 在界面添加UIView和按钮;2. 编写代码实现滤镜功能

6. 功能实现注意事项

在实现上述功能时,有一些注意事项需要我们关注,以确保功能的正常运行。

6.1 3D Touch功能

  • 设备兼容性 :3D Touch功能仅在支持该功能的设备上可用,如iPhone 6S、6S Plus和iPhone 7系列。在代码中需要进行设备检测,避免在不支持的设备上出现错误。
  • 模拟器模拟 :虽然可以使用配备Force Trackpad的Macbook在iOS模拟器中模拟3D Touch,但这只是一种近似模拟,与真实设备的体验仍有差异,建议在真实设备上进行测试。

6.2 设置功能

  • UserDefaults存储类型 :UserDefaults只能存储特定类型的对象,如字符串、数字、日期、数组、数据和字典。在存储和读取设置信息时,要确保数据类型的正确性。

6.3 图像滤镜功能

  • Core Image框架 :使用Core Image框架时,要注意滤镜的名称和参数的正确性。可以参考Core Image Filter Reference获取完整的滤镜列表和使用说明。
  • 图像转换 :在将处理后的CIImage转换为UIImage时,建议先转换为CGImage,再转换为UIImage,避免出现图像显示异常的问题。

7. 功能扩展建议

除了上述已经实现的功能,还可以对应用进行进一步的扩展,以提升用户体验和应用的实用性。

7.1 3D Touch功能扩展

  • 增加更多快速操作 :可以在主屏幕快速操作中添加更多的菜单项,如快速分享、快速搜索等,方便用户快速访问常用功能。
  • 优化Peek and Pop体验 :可以在预览界面中添加更多的交互元素,如分享按钮、收藏按钮等,让用户在预览时就能进行一些操作。

7.2 设置功能扩展

  • 增加更多设置项 :可以添加更多的设置项,如字体大小、主题颜色等,让用户可以根据自己的喜好定制应用的外观和功能。
  • 同步设置信息 :可以将设置信息同步到云端,让用户在不同设备上都能使用相同的设置。

7.3 图像滤镜功能扩展

  • 增加更多滤镜效果 :可以添加更多的滤镜效果,如复古滤镜、艺术滤镜等,满足用户不同的审美需求。
  • 支持滤镜组合 :允许用户将多个滤镜组合使用,创造出独特的图像效果。

通过以上的功能扩展建议,可以进一步提升应用的竞争力和用户满意度。在实际开发中,可以根据应用的需求和用户的反馈,选择合适的扩展方向进行开发。

【永磁同步电机】基于模型预测控制MPC的永磁同步电机非线性终端滑模控制仿真研究(Simulink&Matlab代码实现)内容概要:本文围绕永磁同步电机(PMSM)的高性能控制展开,提出了一种结合模型预测控制(MPC)非线性终端滑模控制(NTSMC)的先进控制策略,并通过SimulinkMatlab进行系统建模仿真验证。该方法旨在克服传统控制中动态响应慢、鲁棒性不足等问题,利用MPC的多步预测和滚动优化能力,结合NTSMC的强鲁棒性和有限时间收敛特性,实现对电机转速和电流的高精度、快速响应控制。文中详细阐述了系统数学模型构建、控制器设计流程、参数整定方法及仿真结果分析,展示了该复合控制策略在抗干扰能力和动态性能方面的优越性。; 适合人群:具备自动控制理论、电机控制基础知识及一定Matlab/Simulink仿真能力的电气工程、自动化等相关专业的研究生、科研人员及从事电机驱动系统开发的工程师。; 使用场景及目标:①用于深入理解模型预测控制滑模控制在电机系统中的融合应用;②为永磁同步电机高性能控制系统的仿真研究实际设计提供可复现的技术方案代码参考;③支撑科研论文复现、课题研究或工程项目前期验证。; 阅读建议:建议读者结合提供的Simulink模型Matlab代码,逐步调试仿真环境,重点分析控制器设计逻辑参数敏感性,同时可尝试在此基础上引入外部扰动或参数变化以进一步验证控制鲁棒性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值