【ios开发/Xcode】实现多功能备忘录
- 引言
- 具体功能及实现
- 登录界面主要源代码
- 注册界面主要源代码
- 注册界面主要源代码
- 增删改查主要源代码
- 音乐播放器界面源代码
- 计算器界面源代码
- 所有源码下载
- 总结
引言
一、项目来源及意义
随着当今时代科技不断的进步发展,现代快节奏的生活方式让人们每天都有很多行程安排,都是往往因为事务的堆积导致人们经常把要做的事务遗忘,或者想要及时记录的信息得不到记录。
在今天这个充斥着各种激烈竞争的重压时代,每个人都在忙碌的生活着。当今时代下对下一代人要培养很多特长的同时还要让他们完成学校布置的作业,而我们作为大学生学习任务同样很重,还面临这就业等问题,在我们这般的忙碌琐碎日常生活中,会有很多需要记忆的工作。但人的记忆是有限的,我们需要一个能提醒和安排我们工作的东西,如何井井有条的处理和安排任务,在有限的时间内完成最紧急最重要的事情,备忘录对我们而言尤为重要。
同时,在平常工作劳累之余的碎片化时间中,如何简单的放松自我也是及其重要的问题。因此我推出了一个简单易操作的多功能备忘录,在记录保存重要的信息的同时还附带计算与放松功能,极其好用。
二、项目开发平台及技术简要说明
系统:MAC OS 10.14
环境:XCode 10.2 Swift 4.3
三、项目需求分析及设计
该项目主要实现了一个多功能备忘录,包括随笔便签、计算器以及音乐播放器。在随笔便签中,每个人所保存的便签信息不同,所以根据账号可以实现显示不同的便签信息。而在需要添加便签时,可以写入新便签,并以标题的形式显示。在管理便签信息的时候可以进行删除或者调整次序等操作,当然数据要能够持久化保存。而计算器与音乐播放器则可以直接进行使用。
用户能够在注册页面注册新的账号,在使用账号登录成功后转入登录成功界面,管理和查看页面中可以查看当前存在的便签,以标题和时间的形式显示。接着能够进行信息编辑包括增加删除和修改次序等等。让你做到一件事都不漏,完全帮你管理起你的生活和工作。
在未登录时,用户可以使用计算器进行对一些事物以及数据的计算,较为方便。同时还能够听听音乐,放松放松。音乐还提供的多倍数与低倍数功能,能够尽情的根据自己的兴趣调节,非常人性化。
综上所述,根据这些功能该项目总共设计了7个主要页面:欢迎界面、登录页面、注册页面、管理和查看页面、编辑页面、音乐播放界面以及计算器界面。
四、项目实现
项目代码结构
项目故事版
具体功能及实现
注:@开头的这些代码都是需要关联控键,都需要自行在故事板中(Storyboards)进行关联
1、登录
输入系统中已经存储的或注册的账号密码可以进行登录
登录界面主要源代码
class LoginViewController : UIViewController{
//键盘识别
@IBAction func dismissKeyborad(_ sender: UITapGestureRecognizer) {
userId.resignFirstResponder()
password.resignFirstResponder()
}
//用户名
@IBOutlet weak var userId: UITextField!
//密码
@IBOutlet weak var password: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
var userpwd = [String:String]()
//登录
@IBAction func Login(_ sender: UIButton) {
let user = userId.text!
let pwd = password.text!
userpwd = UserDefaults.standard.object(forKey: "userpwd")as?[String:String] ?? [String:String]()
if userpwd[user] == pwd {
self.performSegue(withIdentifier: "LoginSuccess", sender: nil)
} else {
let alertController = UIAlertController(title: "登录失败!",message: nil, preferredStyle: .alert)
self.present(alertController, animated: true,completion: nil)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {self.presentedViewController?.dismiss(animated: false, completion: nil)}
}
}
}
2、注册
若无账号密码则需要注册,点击输入用户名与密码后点击注册即可完成注册,注册成功后弹窗显示“注册成功!”
注册界面主要源代码
class RegisterViewController : UIViewController{
@IBOutlet weak var userId: UITextField!
@IBOutlet weak var password: UITextField!
@IBAction func dismissKeyBoard1(_ sender: UITapGestureRecognizer) {
userId.resignFirstResponder()
password.resignFirstResponder()
}
var userpwd = [String:String]()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//返回
@IBAction func backLo(_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
}
//注册
@IBAction func register(_ sender: Any) {
let user = userId.text!
let pwd = password.text!
userpwd = UserDefaults.standard.object(forKey: "userpwd")as?[String:String] ?? [String:String]()
userpwd[user] = pwd
UserDefaults.standard.set(userpwd, forKey: "userpwd")
UserDefaults.standard.synchronize()
let ok = UIAlertAction(title:"确定", style:.default){
action in self.dismiss(animated: true,completion: nil)
}
let alter = UIAlertController(title: "注册成功!",message: nil, preferredStyle: .alert)
alter.addAction(ok)
self.present(alter,animated:true,completion:nil)
}
}
3、备忘录
此功能为备忘录的主页面,页面中有“返回”、“添加”与“编辑”按钮,点击对应按钮实现对应功能。
注册界面主要源代码
class EducationalSystemViewController : UITableViewController{
var studentList: StudentList
//增加
@IBAction func addStudent(_ sender: UIButton) {
let theStudent = studentList.addStudent()
if let theIndex = studentList.students.index(of:theStudent){
let theIndexPath = IndexPath(row: theIndex, section: 0)
tableView.insertRows(at: [theIndexPath], with: .automatic)
}
studentList.saveStudents()
}
//返回
@IBAction func back(_ sender: UIButton) {
self.dismiss(animated: true, completion: nil)
}
//编辑
@IBAction func shiftEditMode(_ sender: UIButton) {
if isEditing{
sender.setTitle("编辑", for: .normal)
setEditing(false, animated: true)
}else{
sender.setTitle("确定", for: .normal)
setEditing(true, animated: true)
}
}
override func viewDidLoad() {
studentList = StudentList()
let statusBarHeight = UIApplication.shared.statusBarFrame.height
let insets = UIEdgeInsets(top: statusBarHeight, left: 0, bottom: 0, right: 0)
tableView.contentInset = insets
tableView.scrollIndicatorInsets = insets
let theRefreshControl = UIRefreshControl()
theRefreshControl.attributedTitle = NSAttributedString(string: "refreshing")
theRefreshControl.addTarget(self, action: #selector(refreshing), for: UIControl.Event.valueChanged)
refreshControl = theRefreshControl
}
@objc func refreshing(){
if(refreshControl?.isRefreshing == true){
refreshControl?.attributedTitle = NSAttributedString(string: "loading...")
refreshControl?.endRefreshing()
refreshControl?.attributedTitle = NSAttributedString(string: "refreshing")
tableView.reloadData()
}
}
required init?(coder aDecoder: NSCoder) {
studentList = StudentList()
super.init(coder: aDecoder)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return studentList.students.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath) as! StudentCell
let student = studentList.students[indexPath.row]
cell.nameLabel.text = student.name
cell.scoreLabel.text = "(student.score)"
cell.idLabel.text = student.id
return cell
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
let theStudent = studentList.students[indexPath.row]
studentList.deleteStudent(theStudent)
tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
studentList.transferPosition(sourceIndex: sourceIndexPath.row, destinationIndex: destinationIndexPath.row)
}
}
4、备忘录增删改查、数据持久化等操作
点击“添加”,则会在备忘录的最后添加一条备忘录信息,点击“编辑”进入编辑界面,可以移动和删除备忘录中的信息。
增删改查主要源代码
class StudentList{
var students=[Student]()
let archiveURL: URL = {
let documents = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let document = documents.first!
return document.appendingPathComponent("studentistList1.plist")
}()
init(){
let fileExist = FileManager.default.fileExists(atPath: archiveURL.path)
if !fileExist {
let bundlePath = Bundle(for: StudentList.self).resourcePath as NSString?
let thePath = bundlePath!.appendingPathComponent("studentsCollection.plist")
do{
try FileManager.default.copyItem(atPath: thePath, toPath: archiveURL.path)
}catch{
print("fail to copy plist file!")
}
}
let theCollection = NSMutableArray(contentsOfFile: archiveURL.path)!
for theElement in theCollection{
let dict = theElement as! NSDictionary
let name = dict["name"] as! String
let score = dict["score"] as! String
let id = dict["id"] as! String
let theStudent = Student(name: name, score: score, id: id)
students.append(theStudent)
}
}
//增加
func addStudent() -> Student {
let theStudent = Student(name: "今天", score: "准备答辩!", id: "8:00")
students.append(theStudent)
saveStudents()
return theStudent
}
//删除
func deleteStudent(_ theStudent:Student) {
if let theIndex = students.index(of: theStudent){
students.remove(at: theIndex)
saveStudents()
}
}
//修改
func transferPosition(sourceIndex: Int, destinationIndex: Int) {
if sourceIndex != destinationIndex {
let theStudent = students[sourceIndex]
students.remove(at: sourceIndex)
students.insert(theStudent, at: destinationIndex)
}
return
}
//保存
func saveStudents() -> Bool{
let studentsArray = NSMutableArray()
for theStudent in students{
let studentDictionary : NSDictionary
studentDictionary = ["name":theStudent.name,"id":theStudent.id,"score":"(theStudent.score)"]
studentsArray.add(studentDictionary)
}
studentsArray.write(toFile: archiveURL.path,atomically: true)
print(archiveURL)
return true
}
}
下图所示为备忘录初始储存的备忘信息
5、音乐播放器
在“放松一下”功能中可以播放一段优美的音乐,同时能够根据自己的心情调节音乐的快慢,点击对应的按钮即可实现。
音乐播放器界面源代码
class bgmController: UIViewController {
//图片展示
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
//获取图片路径
guard let path = Bundle.main.path(forResource: "p1.gif", ofType: nil),
let data = NSData(contentsOfFile: path),
let imageSource = CGImageSourceCreateWithData(data, nil) else { return }
var images = [UIImage]()
var totalDuration : TimeInterval = 0
for i in 0..<CGImageSourceGetCount(imageSource) {
guard let cgImage = CGImageSourceCreateImageAtIndex(imageSource, i, nil) else { continue }
let image = UIImage(cgImage: cgImage)
i == 0 ? imageView.image = image : ()
images.append(image)
guard let properties = CGImageSourceCopyPropertiesAtIndex(imageSource, i, nil) as? NSDictionary,
let gifDict = properties[kCGImagePropertyGIFDictionary] as? NSDictionary,
let frameDuration = gifDict[kCGImagePropertyGIFDelayTime] as? NSNumber else { continue }
totalDuration += frameDuration.doubleValue
}
imageView.animationImages = images
imageView.animationDuration = totalDuration
imageView.animationRepeatCount = 0
imageView.startAnimating()