iOS 独立开发记录(上)

个月前,完成了个人App的2.0版本,也在普天同庆的六一儿童节这天上架了。因为是个人开发,很多实现都是边探索边做。现在完成之后再回顾,发现自己走了些弯路。所以写了这篇总结,概览了从想法、设计、开发到最终发布的过程。希望读者参考本文,可以少走一些弯路;另外,本文也给列出了开发中具体思路和资源列表。

知识从何而来?

Apple的知识又是从何而来?是哪些人在创造这些机制,又是哪些人在传播这些机制?为什么要这样设计呢?为什么要这样编码呢?

iOS开发是在询问什么问题?技术的实现,究竟是在问什么?为什么要这样做?那样做?评价的标准为何?

资源

我在开发过程中常使用的资源:

  • 相关书籍寻找大致实现方向,我有庞大的电子书库,在此感谢学校提供的优质资源。很多书,都会先检视阅读一遍,这样心中有地图,开发时就可快速定位。书本是理论的简单系统化表示。
  • Apple 官方文档 视频 示例代码系统化的概览,具体可使用内容的查找。
  • StackOverflow主要是查找一些细节问题。
  • Github上的相关项目看具体的代码实现,分析不同实现的优缺点,取其精华去其糟粕。
  • Raywenderlich可以很快上手入门新知识点。
  • 博客
  • 论文
  • 对于想深入理解的知识,会参考相关论文。

搜索时使用google或者bing,绝对可以节约你的时间。时间即是生命。

我选择的简单是易用SS,我的推介链接。

想法

  • 目标:简洁优雅易用节拍器
  • 用户:学习乐器演奏的群体
  • 使用场景:乐器演奏
  • 做什么:小而美。好看,好用,占内存小。
  • 不做什么:不做专业程度极高,功能十分完备的节拍器。

设计

我一般使用Sketch进行快速原型设计。

同时思考,是否可实现?

开发

我使用的是coding的仓库,git进行版本管理。

主要介绍2.0版本中的一些开发过程。

你可以免费下载,看看有哪些基本功能。

多主题设计

配色

参考网站:

  • https://coolors.co/browser
  • http://uigradients.com/#Jonquil
  • http://www.rocket-design.fr/color-template/
  • http://www.shejidaren.com/examples/tools/color-scheme/
  • http://www.shejidaren.com/mbe-style.html
  • http://www.peise.net/

扁平化颜色库:

Chameleon is a lightweight, yet powerful, color framework for iOS (Objective-C & Swift). It is built on the idea that software applications should function effortlessly while simultaneously maintaining their beautiful interfaces.

https://github.com/ViccAlexander/Chameleon

多主题实现

OC版:

https://github.com/Draveness/DKNightVersion

Swift版:

http://www.jianshu.com/p/a5cd0176bcf5

https://github.com/zhangbozhb/ChameleonSwift

  1. theme
  2. view

部分配色表:

Name defaultColor SeaColor GreenColor CoffeeColor  
backgroundColor          
BlockColor rgba(184, 184, 184, 1) #D5EBE9 #F4ADA2 #D4C38F  
BlockColorFill rgba(251, 251, 251, 1) #F5FAF9 #F07973 #EFDFAF  
BlockBdrColor rgba(57, 57, 57, 1) #38465F #38465F #272727  
shadowColor rgba(41, 44, 48, 1) #38465F #A0785C #5D4531  
Sliderstart rgba(184, 184, 184, 1) #F5FAF9 #F2F2F2 #88DEF2  
Sliderend rgba(185, 200, 245, 1) #B0D5C2 #F4ADA2 #FAD199  
SliderBackground Black #364960 #3A4C39 #2B2B2B  
nameIncDecTextColor Black White Black Black  
labelColor Black white Black Black  

根据图片配色举例:

代码实现:

1.Struct方式

public protocol YXYTheme {

// MetreView

var blockColor              : UIColor { get set }

var blockFillColor          : UIColor { get set }

var blockBdrColor           : UIColor { get set }

var blockShadowColor        : UIColor { get set }

// View

var backgroundColor         : UIColor { get set }

var nameIncDecTextColor     : UIColor { get set }

var labelColor              : UIColor { get set }

var incAndDecLabelTextColor : UIColor { get set }

// Slider

var sliderBackgroundColor   : UIColor { get set }

var sliderStartColor        : UIColor { get set }

var sliderEndColor          : UIColor { get set }

var sliderHandleColor       : UIColor { get set }

}

struct DarkTheme : YXYTheme, AnyObjectConvertible {

var blockColor              = UIColor(red:0.72, green:0.72, blue:0.72, alpha:1)

var blockFillColor          = UIColor(red:0.95, green:0.95, blue:0.95, alpha:1)

var blockBdrColor           = UIColor(red:0.21, green:0.21, blue:0.21, alpha:1)

var blockShadowColor        = UIColor(red:0.16, green:0.17, blue:0.19, alpha:1)

var backgroundColor         = UIColor(red:0.34, green:0.34, blue:0.34, alpha:1)

var nameIncDecTextColor     = UIColor(red:0.95, green:0.95, blue:0.95, alpha:1)

var labelColor              = UIColor.whiteColor()

var incAndDecLabelTextColor = UIColor.whiteColor()

var sliderBackgroundColor   = UIColor.lightGrayColor()

var sliderStartColor        = UIColor.grayColor()

var sliderEndColor          = UIColor.greenColor()

var sliderHandleColor       = UIColor.greenColor()

}

2.class 方式

//

//  LightTheme.swift

//  GuitarFere

//

//  Created by youxinyu on 16/3/10.

//  Copyright © 2016年 yogayu.github.io. All rights reserved.

//

import UIKit

class LightTheme : NSObject, YXYTheme, AnyObjectConvertible

{

var blockColor              = UIColor(red:0.72, green:0.72, blue:0.72, alpha:1)

var blockFillColor          = UIColor(red:0.95, green:0.95, blue:0.95, alpha:1)

var blockBdrColor           = UIColor(red:0.21, green:0.21, blue:0.21, alpha:1)

var blockShadowColor        = UIColor(red:0.16, green:0.17, blue:0.19, alpha:1)

var backgroundColor         = UIColor.whiteColor()

var nameIncDecTextColor     = UIColor(red:0.95, green:0.95, blue:0.95, alpha:1)

var labelColor              = UIColor.whiteColor()

var incAndDecLabelTextColor = UIColor.whiteColor()

var sliderBackgroundColor   = UIColor.lightGrayColor()

var sliderStartColor        = UIColor.grayColor()

var sliderEndColor          = UIColor.redColor()

var sliderHandleColor       = UIColor.greenColor()

init( blockColor:UIColor, blockFillColor:UIColor, blockBdrColor:UIColor, blockShadowColor:UIColor,

backgroundColor:UIColor, nameIncDecTextColor:UIColor, labelColor:UIColor, incAndDecLabelTextColor:UIColor,

sliderBackgroundColor:UIColor, sliderStartColor:UIColor, sliderEndColor:UIColor, sliderHandleColor:UIColor){

self.blockColor = blockColor

self.blockFillColor = blockFillColor

self.blockBdrColor = blockBdrColor

self.blockShadowColor = blockShadowColor

self.backgroundColor = backgroundColor

self.nameIncDecTextColor = nameIncDecTextColor

self.labelColor = labelColor

self.incAndDecLabelTextColor = incAndDecLabelTextColor

self.sliderBackgroundColor = sliderBackgroundColor

self.sliderStartColor = sliderStartColor

self.sliderEndColor = sliderEndColor

self.sliderHandleColor = sliderHandleColor

}

}

本地化

参见我之前博文:

http://www.jianshu.com/p/782aaf3bf7da

http://azureyu.com/2016-05-14-iOS-Localizable.html

保持用户设置

let userDefaultsLastTempoKey = "DefaultsTempoKey"

let defaults = NSUserDefaults.standardUserDefaults()

func saveTempo(tempo:Int){

defaults.setInteger(tempo, forKey: userDefaultsLastTempoKey)

defaults.synchronize()

}

读取:

func initialTempo(){

let savedTempo = NSUserDefaults.standardUserDefaults().objectForKey( userDefaultsLastTempoKey) as? Int

if let tempo = savedTempo {

metronome.tempo = tempo

tempoLabel.text = "\(metronome.tempo)"

}else {

tempoLabel.text = "\(metronome.tempo)"

}

Struct如何转为AnyObject?

参考:

https://github.com/tarunon/AnyObjectConvertible

class Box<T> {

let value: T

init(value: T) {

self.value = value

}

}

NSNotificationCenter.defaultCenter().postNotificationName("foo", object: Box(value: YourOwnStruct())) // OK

But Box<T> unwrap is too lazy.

let value = (notification.object as? Box<YourOwnStruct>)?.value

You can cast your struct/enum directory if implement AnyObjectConvertible at that type.

extension YourOwnStruct: AnyObjectConvertible {}

NSNotificationCenter.defaultCenter().postNotificationName("foo", object: YourOwnStruct()) // OK

let value = notification.object as? YourOw

存储用户当前主题设置

初始显示,无法使用函数更改,为什么?

解决:因为存的内容不对,主题是一个Struct或Class。

func initTheme() {

let savedTheme = retrieveTheme()

if let theme = savedTheme {

UIApplication.ch_switchTheme(lightTheme)

}else{

// ...

}

}

GuitarFere[20074:736310] * Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘Attempt to insert non-property list object GuitarFere.Box<GuitarFere.YXYTheme> for key DefaultThemeKey’

The code you posted tries to save an array of custom objects to NSUserDefaults. You can’t do that. Implementing the NSCoding methods doesn’t help. You can only store things like NSArray, NSDictionary, NSString, NSData, NSNumber, and NSDate in NSUserDefaults.
You need to convert the object to NSData (like you have in some of the code) and store that NSData in NSUserDefaults. You can even store an NSArray of NSData if you need to.
When you read back the array you need to unarchive the NSData to get back your BC_Personobjects.
http://stackoverflow.com/questions/19720611/attempt-to-set-a-non-property-list-object-as-an-nsuserdefaults

func saveTheme(theme:LightTheme){

//    let archivedObject = NSKeyedArchiver.archivedDataWithRootObject((theme as? NSObject)!)

let archivedObject = NSKeyedArchiver.archiveRootObject(theme as NSObject, toFile: userDefaultsLastThemeKey)

defaults.setObject(archivedObject, forKey: userDefaultsLastThemeKey)

defaults.synchronize()

}

存:

func saveTheme(theme:LightTheme){

//    let archivedObject = NSKeyedArchiver.archivedDataWithRootObject((theme as? NSObject)!)

let archivedObject = NSKeyedArchiver.archiveRootObject(theme as NSObject, toFile: userDefaultsLastThemeKey)

defaults.setObject(archivedObject, forKey: userDefaultsLastThemeKey)

defaults.synchronize()

}

上面解决方式还是有问题。

突然想到,不用保存主题本身,直接保存是第几个(Int)主题就好。

问题就这样解决了。

摇一摇换肤

override func canBecomeFirstResponder() -> Bool {

return true

}

override func motionBegan(motion: UIEventSubtype, withEvent event: UIEvent?) {

if(event?.subtype == UIEventSubtype.MotionShake) {

randomTheme()

print("shacked")

self.setNeedsStatusBarAppearanceUpdate()

}

}

func randomTheme() {

let max = themes.count - 1

let index = randomIn(min: 0, max: max)

let randomTheme = themes[index]

saveTheme(index)

UIApplication.ch_switchTheme(randomTheme)

}

钟摆绘制

主要使用图像绘制。

例如绘制三角形:

func drawTriangle()  {

//1.获得图形上下文

let context = UIGraphicsGetCurrentContext()

//绘制三角形

let height = self.frame.height

let width = self.frame.width

CGContextMoveToPoint(context, 0, 0)

CGContextAddLineToPoint(context, width, height/2)

CGContextAddLineToPoint(context, 0, height)

//关闭路径,闭环,(连接起点和最后一个点)

powerOffColor.setFill()

CGContextClosePath(context)

//显示在view上

CGContextFillPath(context)

}

时间: 2024-10-09 01:20:43

iOS 独立开发记录(上)的相关文章

iOS 独立开发记录(下)

侧边菜单栏 查看Github上相关实现,一开始选择的是SlideMenuControllerSwift,后来决定更改为自定义,使用更简洁的方式. 分离 分离之前的SliderMeanController,再添加动画. 1.MainViewControllerremove: extension MainViewController:SlideMenuControllerDelegate{ func leftWillOpen() { print("SlideMenuControllerDelegat

iOS蓝牙开发(上)基础以及连接外设的实现

蓝牙常见名称和缩写 MFI ======= make for ipad ,iphone, itouch 专们为苹果设备制作的设备 BLE ==== buletouch low energy,蓝牙4.0设备因为低耗电,所以也叫做BLE peripheral,central == 外设和中心,发起连接的时central,被连接的设备为perilheral service and characteristic === 服务和特征 每个设备会提供服务和特征,类似于服务端的api,但是机构不同.每个外设会

ios应用内购买开发记录教程 ios iap In-App Purchases

以下问题在2014年7月测试的.不保证以后有啥不一样的 1.在iTunes Connect里添加应用,标题/截图/描述/关键字不能更改,icon和包名可以更改.添加后应用不能删除. 2.在In-App Purchases里添加商品,没有4个类型的选项.原因:iTunes Connect上的“Contracts, Tax, and Banking”信息没有设置 3.In-App Purchases的商品添加后无法删除. 4.ios6模拟器可以测试,ios7模拟器测试会说无法连上iTunes.“Er

史上最全最完整的IOS 游戏开发 PDF电子书定制下载

<iOS 5游戏开发>作者:(新西兰)James·Sugrue著 页数:191 出版社:北京市:人民邮电出版社 出版日期:2012.08 简介:<iOS5游戏开发>是一本iOS5游戏开发的基础入门书.全书使用通俗易懂的简单实例,带领读者经历构建经典动作游戏的整个周期.读者在本书的阅读过程中,将经历从开发概念.规划设计一直到编写实际代码的全过过程.本书的每一章,都将演示游戏创建过程中的一个逻辑步骤,读者将在其中学习如何创建Sprite,用触摸屏.重力感应器和屏幕游戏棒控制玩家角色等-

【开发记录】iOS中使用 Reachability 检测网络

如果你想在iOS程序中提供一仅在wifi网络下使用(Reeder),或者在没有网络状态下提供离线模式(Evernote).那么你会使用到Reachability来实现网络检测. 写本文的目的 了解Reachability都能做什么 检测3中网络环境 2G/3G wifi 无网络 如何使用通知 单个controller 多个controller 简单的功能: 仅在wifi下使用 Reachability简介 Reachablity 是一个iOS下检测,iOS设备网络环境用的库. 监视目标网络是否可

IOS开发-图片上传

目前IOS端开发,图片上传到服务器分为两种,一种是直接上到服务器,一种是借助第三方储存(减少服务器压力). 一.直接上传到服务器 1 /** 2 * 代码演示 3 */ 4 //*******UIImagePNGRepresentation(UIImage* image) 要比UIImageJPEGRepresentation(UIImage* image, 1.0) 返回的图片数据量大很多,但从视角角度看,图片的质量没有明显的降低,所以在读取图片数据内容时,可以先使用UIImageJPEGRe

史上最全的iOS多媒体开发博客

这篇博客是史上最全的iOS多媒体开发博客,包括视频.音频.图片等多套API,如果要实现多媒体的功能,点进去找找有用的东西吧:http://www.cnblogs.com/kenshincui/p/4186022.html#autoid-0-0-0..

Jetty JNDI开发实战(上)

Jetty JNDI开发实战(上) 作者:chszs,版权所有,未经同意,不得转载.博主主页:http://blog.csdn.net/chszs 一.JNDI介绍 JNDI即Java Naming and Directory Interface,Java命名和目录接口,是Oracle公司提供的一种标准的Java命名系统接口,允许Java客户端根据命名发现或查询数据和对象.JNDI规范提供了一组标准的独立于命名系统的API,这些API构建在与命名系统有关的驱动之上,有助于将应用与实际的数据源相分

iOS多线程开发——GCD的使用与多线程开发浅析(二)

对于iOS多线程开发,我们时刻处于学习之中,在看书中,看文档中,项目开发中,都可以去提高自己.最近刚看完了<Objective-C高级编程 iOS与OS X多线程和内存管理>这本书后,对多线程有了更为深入的理解,故在此做一个总结与记录.这本书我已经上传至网盘  https://pan.baidu.com/s/1c2fX3EC ,这本书是iOS开发者必读的书之一,写得很不错,欢迎大家下载阅读.书的封面如下,故也称狮子书: . (1)多线程会遇到的问题 . 多线程会出现什么问题呢?当多个线程对同一