Peterfei

上主是我的牧者,我实在一无所缺


  • 首页

  • 归档

  • 标签

百度语音tts Android9.0 发音解决办法

发表于 2019-04-08   |   分类于 前端   |  

百度语音在Android9.0不能发音解决办法:
在 AndroidManifest.xml <application>下加入:

1
<uses-library android:name="org.apache.http.legacy" android:required="false"/>

Swift高级篇

发表于 2016-12-20   |   分类于 Swift   |  

扩展(Extension)

任务: 求数字的平方。

1
2
3
4
// 菜鸟版
func square(x: Int) -> Int { return x * x }
var squaredOfFive = square(x: 5)
square(x: squaredOfFive) // 625

为了求5的四次方我们被迫创建变量 squaredOfFive — 高手可不喜欢被迫定义一个无用的变量。

1
2
3
4
5
6
// 高手版
extension Int {
var squared: Int { return self * self }
}
5.squared // 25
5.squared.squared // 625

泛型(Generics)

任务:打印输出数组内所有的元素。

1
2
3
4
5
6
7
8
9
10
11
// 菜鸟版
var stringArray = ["苍老师", "范老师", "优衣库"]
var intArray = [1, 3, 4, 5, 6]
var doubleArray = [1.0, 2.0, 3.0]
func printStringArray(a: [String]) {
for s in a {
print(s)
}
}
func printIntArray(a: [Int]) { for i in a { print(i) } }
func printDoubleArray(a: [Double]) {for d in a { print(d) } }

居然要定义这么多函数? 菜鸟能忍高手不能忍!

1
2
3
4
5
6
// 高手版
func printElementFromArray(a: [T]) {
for element in a {
print(element)
}
}

For 遍历 vs While 遍历

任务:打印 5 次 大雁塔

1
2
3
4
5
6
// 菜鸟版
var i = 0
while 5 > i {
print("大雁塔")
i += 1
}

被迫定义了变量 i 来确保打印大雁塔5次

1
2
3
4
// 高手版
for _ in 1...5 {
print("大雁塔")
}

计算属性 vs 函数

任务:计算圆的直径

1
2
3
4
5
6
// 菜鸟版
funcgetDiameter(radius: Double) -> Double { return radius * 2}
funcgetRadius(diameter: Double) -> Double { return diameter / 2}
getDiameter(radius: 10) // return 20
getRadius(diameter: 200) // return 100
getRadius(diameter: 600) // return 300

上面我们创建了2个毫无关系的函数,可是直径和周长两者真的没有关系吗?

1
2
3
4
5
6
7
8
9
10
// 高手版
var radius: Double = 10
var diameter: Double {
get { return radius * 2}
set { radius = newValue / 2}
}
radius // 10
diameter // 20
diameter = 1000
radius // 500

函数式编程

任务: 获取偶数。

1
2
3
4
5
6
7
8
// 菜鸟版
var newEvens = [Int]()
for i in 1...10 {
if i % 2 == 0 {
newEvens.append(i)
}
}
print(newEvens) // [2, 4, 6, 8, 10]

这种for循环真是冗长,让人看的昏昏欲睡。

1
2
3
4
// 高手版
var evens = (1...10).filter { $0 % 2 == 0 }
print(evens)
// [2, 4, 6, 8, 10]

swift实现代理,通知,闭包传值

发表于 2016-12-20   |   分类于 Swift   |  

区别

第一就是代理,这也是很常用的方式,特点是一对一的形式,而且逻辑结构非常清晰。实现起来较为简单:写协议 ,设置代理这个属性, 最好在你想通知代理做事情的方法中调用即可。当然这里面有一些细节,包括 ①协议定义时,请用关键字@required,和@optional来明确代理是否必须实现某些方法 ②代理的类型需用id类型,并写明要遵守的协议 ③就是在调用代理方法的时候需要判断代理是否实现该方法。

第二就是通知,通知的优点很明显,他是一对多的形式,而且可以在任意对象之间传递,不需要二者有联系,当然他的实现和代理相比较稍微绕一点,注册,发通知,收通知。这里面的注意点就是 ①对于系统没有定义的事件监听时需要自己发通知,这是你就需要定义一个key,字符串类型,这也是通知的一个弊端,你需要拷贝到收通知的对象,避免写错一个字母而无法收通知的尴尬 ②就是注册的通知中心需要手动移除,不然除了性能的问题还会有其他的问题出现,比如说一个控制器消失了之后还有因为某些事件而发出通知,造成不想要的结果。

第三就是block了,这是苹果后来才加入的,也是目前开发比较常用的一种方式,功能比较强大,但是在理解和使用上可能需要一段时间摸索和熟悉。他的最大特点就是回调,而且回调时可以传入参数,最重要的是,无论在哪调用,block的执行都会回到block创建的地方执行,而非调用的地方。而block本身可以封装一段代码,一段代码你懂的,很多人在初学时会被搞晕,甚至在block的声明上就纠结,其实很正常,多用就好。

代理

如下面代码,我们定义了一个协议方法, 其结构就是protocol关键字+协议的名称 + : + NSObjectProtocol {},注意Swift中的自定义协议其本身必须遵循NSObjectProtocol协议

1
2
3
4
protocol TextViewControllerDelegate: NSObjectProtocol{
// 点击delegate按钮回调
func delegateBtnWillClick(message : String)
}

并且在OC中,我们一般会定义一个属性来保存代理如@property (nonatomic,weak)id< TextViewControllerDelegate > delegate;但是在Swift中我们依然要这样做,只不过写法变成了weak var delegate : TextViewControllerDelegate?,注意一定要加上weak关键字,避免循环引用问题.这是我的demo中的代码,回调一段字符串

1
2
3
4
5
6
7
8
/MARK: - 点击代理传值按钮
func delegateBtnClick()
{
print("代理传值按钮被点击")
let str = "代理传值按钮被点击,把上个界面的值传了过来"
delegate?.delegateBtnWillClick(str)
self.navigationController?.popViewControllerAnimated(true)
}

然后就在别的控制器,设置那个控制器为该控制器的代理,去实现协议方法就可以了

使用SnapKit作应用新手上路导览

发表于 2016-09-14   |   分类于 前端   |  

具体实现:
YMNewfeatureViewController.swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import UIKit
import SnapKit
let newFeatureID = "newFeatureID"
class YMNewfeatureViewController: UICollectionViewController {
/// 布局对象
private var layout: UICollectionViewFlowLayout = YMNewfeatureLayout()
init() {
super.init(collectionViewLayout: layout)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.registerClass(YMNewfeatureCell.self, forCellWithReuseIdentifier: newFeatureID)
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return kNewFeatureCount
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(newFeatureID, forIndexPath: indexPath) as! YMNewfeatureCell
cell.imageIndex = indexPath.item
return cell
}
// 完全显示一个cell之后调用
override func collectionView(collectionView: UICollectionView, didEndDisplayingCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
let path = collectionView.indexPathsForVisibleItems().last!
if path.item == (kNewFeatureCount - 1) {
let cell = collectionView.cellForItemAtIndexPath(path) as! YMNewfeatureCell
cell.startBtnAnimation()
}
}
}
/// YMNewfeatureCell
private class YMNewfeatureCell: UICollectionViewCell {
private var imageIndex: Int? {
didSet {
iconView.image = UIImage(named: "walkthrough_\(imageIndex! + 1)")
}
}
func startBtnAnimation() {
startButton.hidden = false
// 执行动画
startButton.transform = CGAffineTransformMakeScale(0.0, 0.0)
startButton.userInteractionEnabled = false
// UIViewAnimationOptions(rawValue: 0) == OC knilOptions
UIView.animateWithDuration(2, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 5, options: UIViewAnimationOptions(rawValue: 0), animations: { () -> Void in
// 清空形变
self.startButton.transform = CGAffineTransformIdentity
}, completion: { (_) -> Void in
self.startButton.userInteractionEnabled = true
})
}
override init(frame: CGRect) {
super.init(frame: frame)
setupUI()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupUI() {
contentView.addSubview(iconView)
contentView.addSubview(startButton)
iconView.snp_makeConstraints { (make) in
make.edges.equalTo(contentView)
}
startButton.snp_makeConstraints { (make) in
make.bottom.equalTo(contentView.snp_bottom).offset(-50)
make.size.equalTo(CGSizeMake(150, 40))
make.centerX.equalTo(0)
}
}
private lazy var iconView = UIImageView()
private lazy var startButton: UIButton = {
let btn = UIButton()
btn.setBackgroundImage(UIImage(named: "btn_begin"), forState: .Normal)
btn.addTarget(self, action: #selector(startButtonClick), forControlEvents: .TouchUpInside)
btn.layer.masksToBounds = true
btn.hidden = true
return btn
}()
@objc func startButtonClick() {
UIApplication.sharedApplication().keyWindow?.rootViewController = YMTabBarController()
}
}
private class YMNewfeatureLayout: UICollectionViewFlowLayout {
/// 准备布局
private override func prepareLayout() {
// 设置 layout 布局
itemSize = UIScreen.mainScreen().bounds.size
minimumLineSpacing = 0
minimumInteritemSpacing = 0
scrollDirection = .Horizontal
// 设置 contentView 属性
collectionView?.showsVerticalScrollIndicator = false
collectionView?.bounces = false
collectionView?.pagingEnabled = true
}
}

用户首次装载时应用:

1
2
3
4
5
6
if !NSUserDefaults.standardUserDefaults().boolForKey(YMFirstLaunch) {
window?.rootViewController = YMNewfeatureViewController()
NSUserDefaults.standardUserDefaults().setBool(true, forKey: YMFirstLaunch)
} else {
window?.rootViewController = YMTabBarController()
}

Swift 学习之tableView实现

发表于 2016-09-11   |   分类于 Swift   |  

在做移动端开发时,难免会用到tableview 来渲染列表数据,像这样:

实现也很简单,先贴出code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import UIKit
let homeCellID = "homeCellID"
class YMTopicViewController: YMBaseViewController, UITableViewDelegate, UITableViewDataSource, YMHomeCellDelegate {
var type = Int()
var tableView = UITableView()
/// 首页列表数据
var items = [YMHomeItem]()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = YMGlobalColor()
setupTableView()
// 获取首页数据
weak var weakSelf = self
YMNetworkTool.shareNetworkTool.loadHomeInfo(type) { (homeItems) in
weakSelf!.items = homeItems
weakSelf?.tableView.reloadData()
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let homeCell = tableView.dequeueReusableCellWithIdentifier(homeCellID) as! YMHomeCell
homeCell.homeItem = items[indexPath.row]
homeCell.delegate = self
return homeCell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let detailVC = YMDetailViewController()
detailVC.homeItem = items[indexPath.row]
detailVC.title = "攻略详情"
navigationController?.pushViewController(detailVC, animated: true)
}
func homeCellDidClickedFavoriteButton(button: UIButton) {
print("favorite button click")
let loginVC = YMLoginViewController()
loginVC.title = "登录"
let nav = YMNavigationController(rootViewController: loginVC)
presentViewController(nav, animated: true, completion: nil)
}
func setupTableView() {
let tableView = UITableView()
tableView.frame = view.bounds
tableView.delegate = self
tableView.dataSource = self
tableView.rowHeight = 160
tableView.separatorStyle = .None
tableView.contentInset = UIEdgeInsetsMake(kTitlesViewY + kTitlesViewH, 0, tabBarController!.tabBar.height, 0)
tableView.scrollIndicatorInsets = tableView.contentInset
let nib = UINib(nibName: String(YMHomeCell), bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: homeCellID)
view.addSubview(tableView)
self.tableView = tableView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}

阅读全文 »
1…567…16
peterfei

peterfei

peterfei|技术|上主是我的牧者

79 日志
14 分类
62 标签
RSS
github
© 2025 peterfei
由 Hexo 强力驱动
主题 - NexT.Mist