看英文视频加中文字幕,效率也是蛮低的,下个星期六博览网的 iOS 极客班就开学了,希望能够认真高效投入更多时间去学习,一定要学好,找到开发的工作,圆毕业三年的一个梦。

Swift 学习还算顺利,MVC 模式也有所熟悉,就是独自开发和想法实现有困难,暂时停留在看懂和自己写一遍的水平。

还有就是玩手机,刷微博啥的超级浪费时间,因为这个不费脑,玩的也高兴,能够一天不吃饭,也不困,也停不下来。
但是学习或看书,就很费神,容易犯困,这个一定要克服,实在困了就休息10分钟,再继续。

New Calculator Demo

  • Applying MVC to the Calculator
  • enum
  • Simple initializer
  • Returning an Optional
  • Dicionary
  • Tuples

源码如下,待修改:

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
//
// CalculatorBrain.swift
// Calculator
//
// Created by Will Ge on 7/11/15.
// Copyright © 2015 gewill.org. All rights reserved.
//

import Foundation

class CauculatorBrain
{
// 定义一个枚举类型,来分类表示输入的:运算数、一元运算和二元运算
enum Op {
case Operand(Double)
case UnaryOperation(String, Double -> Double)
case BinaryOperation(String, (Double, Double) -> Double)
}

// 定义一个数组来储存所有输入
var opStack = [Op]()

// 定义已知运算符
var knownOps = [String:Op]()

// 初始化已知运算符
init() {
knownOps["+"] = Op.BinaryOperation("+", +)
knownOps["−"] = Op.BinaryOperation("−") {$1 - $0}
knownOps["×"] = Op.BinaryOperation("×", *)
knownOps["÷"] = Op.BinaryOperation("÷") {$1 / $0}
knownOps["√"] = Op.UnaryOperation("√", sqrt)
}

// 定义一个函数,把输入递归取出
func evaluate(ops: [Op]) -> (result: Double?, remainingOps:[Op]) {
if !ops.isEmpty {
var remainingOps = ops
let op = remainingOps.removeLast()
switch op {
case.Operand(let operand):
return (operand, remainingOps)
case .UnaryOperation(_, let operation):
let operandEvaluation = evaluate(remainingOps)
if let operand = operandEvaluation.result {
return (operation(operand), operandEvaluation.remainingOps)
}
case .BinaryOperation(_, let operation):
let op1Evaluation = evaluate(remainingOps)
if let operand1 = op1Evaluation.result {
let op2Evaluation = evaluate(remainingOps)
if let operand2 = op2Evaluation.result {
return (operation(operand1, operand2), op2Evaluation.remainingOps)
}


}

}
}
return (nil, ops)
}

func evaluate() -> Double? {
let (result, remainder) = evaluate(opStack)
print("\(opStack) = \(result) with \(remainder) left over")
return result

}

// 运算数
func pushOperand(operand: Double) -> Double? {
opStack.append(Op.Operand(operand))
return evaluate()
}

// 运算符
func performOperation(symbol: String) -> Double? {
if let operation = knownOps[symbol] {
opStack.append(operation)
}
return evaluate()
}
}
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
//
// ViewController.swift
// Calculator
//
// Created by Will Ge on 6/28/15.
// Copyright © 2015 gewill.org. All rights reserved.
//

import UIKit

class ViewController: UIViewController {


@IBOutlet weak var history: UILabel!

@IBOutlet weak var display: UILabel!


var userIsInTheMiddleOfTypingANumber: Bool = false

var brain = CauculatorBrain()

@IBAction func appendDigit(sender: UIButton) {
let digit = sender.currentTitle!
if userIsInTheMiddleOfTypingANumber{
display.text = display.text! + digit
} else {
display.text = digit
userIsInTheMiddleOfTypingANumber = true
}

print("digit = \(digit)")
}



@IBAction func enter() {
userIsInTheMiddleOfTypingANumber = false
if let result = brain.pushOperand(displayValue) {
displayValue = result
} else {
displayValue = 0
}
print("pushOperand = \(displayValue)")

}

@IBAction func operate(sender: UIButton) {

if userIsInTheMiddleOfTypingANumber {
enter()
}
if let operation = sender.currentTitle {
print("\(operation)")
}
}



var displayValue: Double{
get {
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
}
set {
display.text = "\(newValue)"
userIsInTheMiddleOfTypingANumber = false
}
}
}


我的需求: www.gewill.org 跳转到 gewill.org。

使用万网域名服务提供的 DNS 解析需要备案才能实现301跳转,所以之前使用 DNSPOD 的服务,但是不知为何竟失效了,gewill.org 能打开,www.gewill.org打不开了。换了其他的也都不行,dig 也是对的。

Google Github Pages 的相关信息,发现官方帮助文档就有简单是实现方案:

Configuring a www subdomain

If you configure both an apex domain (e.g. example.com) and a matching www subdomain (e.g. www.example.com), GitHub’s servers will automatically create redirects between the two.

For example:

If your CNAME file contains example.com, then www.example.com will redirect to example.com.
If your CNAME file contains www.example.com, then example.com will redirect to www.example.com.”

DNS 同时 CNAME 顶级域名和 WWW,然后在 Github CNAME文件中添加偏好的一个。

虽然之前有看过,一则英文看了只解一二,二则当时对于 DNS 和网站都刚刚接触。我学习新鲜东西节奏还是太慢,以后还要多思考,多与人交流。官方文档还是最简洁正确的。

继续 DEMO: Calculator

Swift 能类型推断

自动布局:

  • Pin: Spacing to nearest neighbor, Equal Widths, Equal Heights
  • Resolve Auto Layout Issues: Clear Constraints

87果然是个神奇的数字,我之前没有对齐就开始 Pin,始终无法得到“Add 87 Constraints”,自然没有得到自动对齐的理想布局。

代码如下:

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
//
// ViewController.swift
// Calculator
//
// Created by Will Ge on 6/28/15.
// Copyright © 2015 gewill.org. All rights reserved.
//

import UIKit

class ViewController: UIViewController {


@IBOutlet weak var display: UILabel!

var userIsInTheMiddleOfTypingANumber: Bool = false

@IBAction func appendDigit(sender: UIButton) {
let digit = sender.currentTitle!
if userIsInTheMiddleOfTypingANumber{
display.text = display.text! + digit
} else {
display.text = digit
userIsInTheMiddleOfTypingANumber = true
}

print("digit = \(digit)")
}

var operandStack = Array<Double>()

@IBAction func enter() {
userIsInTheMiddleOfTypingANumber = false
operandStack.append(displayValue)
print("operandStack = \(operandStack)")

}

@IBAction func operate(sender: UIButton) {
let operation = sender.currentTitle!
if userIsInTheMiddleOfTypingANumber {
enter()
}
switch operation {
case "×": performOperation { $0 * $1 }
case "÷": performOperation { $1 / $1 }
case "+": performOperation { $0 + $1 }
case "−": performOperation { $1 - $0 }
case "√": performOperation1 { sqrt($0) }
default: break
}
}

func performOperation(operation: (Double, Double) ->Double) {
if operandStack.count >= 2 {
displayValue = operation(operandStack.removeLast(), operandStack.removeLast())
enter()
}
}

func performOperation1(operation: Double ->Double) {
if operandStack.count >= 2 {
displayValue = operation(operandStack.removeLast())
enter()
}
}


var displayValue: Double{
get {
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
}
set {
display.text = "\(newValue)"
userIsInTheMiddleOfTypingANumber = false
}
}
}

MVC:

  • 各个模块之间的含义
  • 模块之间的通信有无
  • 模块之间的控制关系

MVC

iTunes U 课程地址:iTunes U/Developing iOS 8 Apps Swift

CS193P 课程地址:CS193P iPhone Application Development

字幕下载:https://github.com/x140yu/Developing_iOS_8_Apps_With_Swift

课程不用多介绍,下面直接进入笔记:

iOS 仍是一个 Unix 系统,添加了很多移动方面的模块和优化。

Cocoa Touch 是本课的重点,如涉及 Media 等主题需要自行找资料深入学习。

自己动手写代码,绝不复制粘贴别人的代码。

接下来是 DEMO:Calculator

蓝线是自动布局时的好帮手。

Storyboard 是正方形,自动布局就是实现对真实屏幕比例添加挤压效果或规则,已完成适配。

Trailing Margin (尾部到边框)
Leading Margin (头部到边框)
Top (顶部)

Outline mode (大纲模式)

? 表示 Optional,有两种情况:

  • nil : 值缺失
  • 有值

源码如下:

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

// ViewController.swift


import UIKit

class ViewController: UIViewController {


@IBOutlet weak var display: UILabel!

var userIsInTheMiddleOfTypingANumber: Bool = false

@IBAction func appendDigit(sender: UIButton) {
let digit = sender.currentTitle!
if userIsInTheMiddleOfTypingANumber{
display.text = display.text! + digit
} else {
display.text = digit
userIsInTheMiddleOfTypingANumber = true
}

print("digit = \(digit)")
}

}

Windows 进阶的学习方法博览网Windows专家管理与排错第一讲,讲师彭爱华,其中关于学习方法,尤其是少下载,贪多嚼不烂,击中我要害。虽然讲的是 Windows,但方法还是通用的,以下为学习笔记。

##良好的学习习惯

  • 养成阅读英文资料的习惯
  • 少下载、勤阅读、多动手
  • 知识的整理,善于写博客,多分享
  • 基础知识要扎实,平台和核心领域知识

##关于提问

  • 必须经过仔细思考,才提问,切忌不动脑子
  • 提问不是为了解决眼前问题,而是获得启发
  • 好的问题时带有启发性的,衍生性的
  • 能否整理经典的问题,沉淀下来?(写博客)

##常见弊病

  • 盲目的跟风式学习
  • 吃着碗里,想着锅里
  • 理论不联系实际
  • 不能高效利用资源

原文链接 Minimalism in Web design: past and future,偏软文但是内容是好的。并非全文翻译,取其要旨。大约翻译了4个小时,算是通篇读懂了,还多亏了 Google 的翻译,下次提取大纲好了。

极简主义(Minimalist)以其永恒的优雅和清晰明确的内容显示,是网页设计最为长久的视觉架构之一。

Beatbox

以下为几个网页设计中极简主义的几个原则:

少即是多(Less is More):简史和解构

和平面设计的起源类似的,极简主义在网页设计是通过减法做雕塑的一种最纯净方式–最完美的实现不是没有元素可以添加,而是没有元素可以删去。尽管目前极简主义围绕着负空间和黑色字体-即是极简主义的核心-该风格通过任何手段已达到最低来定义自己。

最小化网页设计基于以下基础,并全部以网站内容为设计中心:

  • 负空间- 通常是指白色空间,负空间简单来说就是在设计中没有被使用的空间。 通常极简主义设计中,你将会看到负空间被充满活力的颜色填充(或者就是简单的留白/灰/黑)。
  • 高清照片 - 因为更少的界面修饰物,用户可以更好地欣赏高清照片的惊艳的细节。通常照片上覆盖幽灵按钮(白色轮廓的按钮)和粗体的文字排版。
  • 有特色的排版 - 不管手写体的标题或是简洁无衬字体的正文,字体方面的极简主义设计少数的领域之一,可以包含少许修饰。如果你感兴趣,可以看一下这些优秀的字体集 20 minimalist typefaces
  • 鲜明的对比 - 对比是通过独立设计元素组合而成。例如在一张黑色图片上使用72点阵的粗体字。又或者白色手写字体用在浅绿色的单色背景上。
  • 简洁的导航栏 - 最复杂的导航栏带有下拉菜单(即使没有没有二级菜单弹出)。更常见的是几个顶部水平的导航栏,甚至汉堡菜单。
  • 视觉上的平衡 - 网页设计对于人眼来说,视觉平衡通过一个明确的视觉层次,一致的对准和定位,以及灵活的利用对称和不对称来实现。

现在你可能觉得极简主义很容易 - 毕竟更少元素的使用意味着更少工作量,对吧? 可事实上正相反:以为你要受限于少量的元素,而这些元素必须是经过细致的关注下和有目标性低挑选出来的。粗糙地使用极简主义是很容易,但正确的使用则不然。

简洁的设计是故意而为之的。它是条从一个框架的不必要的元素只留下所需要的方法。多数简洁的网站设计不会包含了很多色彩(调色板往往只有一种主色),纹理或形状或类似颜色。

极简主义行之有效是因为,它做了所有设计都应该做的 - 把重心放在内容上。

极简主义将继续成为一个受欢迎的选择,但很可能演变成一种少一点鲜明对比的风格。正如我们所看到的技术,如“扁平设计”演变成“全平话设计”,极简主义设计将更丰富(更可用),UI 设计师尝试纹理、颜色和效果 - 以及不在使用对称的图案。

以下让我们看看一些进化的元素:

  • 最小化质感纹理(Minimal texture)
    Minimal texture
  • 反转颜色(Reverse colors)
    Reverse colors
  • 更多互动特效(More interactive effects)
  • 移除对称(Move away from symmetry)
    Move away from symmetry
  • 提高可用性(Improved usability)
    Improved usability

结论

极简主义不仅仅是白色的空间和尽可能使用最少的元素。极简主义哲学的核心是在强调内容。减少元素,并使有大量的负空间追求一个结果 - 他们尽量减少干扰,使用户可以只专注于真正重要的(内容)。

千万不要误解为极简的目的本身,或者你也可能发现自己删除了不可替代的元素。这不是通过减法进行雕塑(代指设计) - 这只是减法。

可以下载 The Curated Collection of Design Techniques: Cards & Minimalism 学习更多极简主义的网页设计内容。

添加分享

###方法一:原生分享

添加分享按钮代码, Hexo 文件夹下/theme/next/layout/_macro/post.swig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html xmlns:wb="http://open.weibo.com/wb">

<script src="http://tjs.sjs.sinajs.cn/open/api/js/wb.js" type="text/javascript" charset="utf-8"></script>

<wb:share-button appkey="2407521490" addition="simple" type="button"></wb:share-button>


<a href="https://twitter.com/share" class="twitter-share-button" data-via="gewillorg" data-size="large" data-count="none">Tweet</a>

<script>
!function(d,s,id){
var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';
if(!d.getElementById(id)){
js=d.createElement(s);
js.id=id;js.src=p+'://platform.twitter.com/widgets.js';
fjs.parentNode.insertBefore(js,fjs);
}
}
(document, 'script', 'twitter-wjs');
</script>

###方案二:ShareThis 定制

更加统一优美的解决方案,有个各种样式可选,非常方便。
稍后我再进行定制,最好是默认黑色,点击激活时恢复彩色。

默认有添加后缀在你的网址,去除方法如下 doNotHash: ture,详情参考:CopyNShare Settings

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

<script type="text/javascript">var switchTo5x=true;</script>
<script type="text/javascript" src="http://w.sharethis.com/button/buttons.js"></script>
<script type="text/javascript">stLight.options({
publisher: "7fb5f31a-b8e7-4aa1-a6eb-9aac8b9b13f0", doNotHash: ture, doNotCopy: false, hashAddressBar: true});
</script>

<span class='st_sina_large' displayText='Sina'></span>
<span class='st_twitter_large' displayText='Tweet'></span>
<span class='st_facebook_large' displayText='Facebook'></span>
<span class='st_googleplus_large' displayText='Google +'></span>
<span class='st_pinterest_large' displayText='Pinterest'></span>
<span class='st_tumblr_large' displayText='Tumblr'></span>
<span class='st_reddit_large' displayText='Reddit'></span>


不蒜子统计

不蒜子”与百度统计谷歌分析等有区别:“不蒜子”可直接将访问次数显示在您在网页上。

添加统计代码, Hexo 文件夹下/theme/next/layout/_partials/footer.swig

Sketch 进阶与技巧

一:App 设计标准

  1. Point (PT)
  • Point (PT) - 表示独立于设备的
    像素点 (在 Android 上叫 DP)
  1. Point (PT)和像素的关系
  • 像素点: 相同 Point 的按钮, 在 Retina 屏幕上的图片像素是非Retina屏幕的两倍
  • 通过 @2x 后缀标识
  1. iPhone 分辨率的终极指南

  2. iOS App 设计尺寸标准

Sketch 界面设计入门和实战

极客学院的视频教程,地址点我。总体上算是入门了,有待熟练要多做几个练习。

一:Sketch 概述

Sketch 的优点

  • 1.矢量
  • 2.文件小
  • 3.画布无限大
  • 4.每个图层都支持多种填充模式
  • 5.Symbol 和 Style
  • 6.强大的文件导出工具
  • 7.自动保留所有历史版本

Sketch 的弱点

  • 位图处理能力弱

二:Sketch 界面功能布局

  • 1.软件布局
  • 2.画布
  • 3.检查器
  • 4.图形列表

三:Sketch 基础工具-图层

  • 1.添加图层

  • Shift 和 Option 的使用

  • 2.选择图层

  • 同时选择多个图层

  • 重叠图层

  • 3.移动图层

    • Shift、Alt、Cmd+D
    • 隐藏图层
  • 4.改变大小

    • Cmd+方向键
    • Cmd+Shift+方向键
  • 5.锁定图层

四:Sketch 基础工具-图形

  • 1.基本图形

  • 2.图形编辑

  • 点的控制手柄

  • 矢量工具

  • 封闭路径 VS 开发路径

  • Shift

    • 选中多个点
  • 添加锚点

  • 3.布尔运算

  • 4.变形工具

  • 5.蒙版

    • 限制蒙版
    • 图形蒙版
    • ALPHA 蒙版
  • 6.剪刀工具

  • 7.复制旋转

五:Sketch 基础工具-文本

  • 1.添加文本

  • 2.文本检查器

  • Text Style

  • 3.文本转换问轮廓

  • 渐变效果

  • 4.文本字体的技巧

  • Fonts:找了半天,原来

六:Sketch 基础工具-图片

  • 1.位图编辑

  • 高斯模糊

  • Color Adjust

  • 反选

  • 剪裁

  • 填充

  • 2.九宫格

七:App 登陆界面制作完整步骤

Imgur

尚有一个 BUG,真机无法加载图片,模拟器可以。

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
//
// ViewController.m
// Photo DEMO
//
// Created by Will on 5/24/15.
// Copyright (c) 2015 gewill.org. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *topLabel;
@property (weak, nonatomic) IBOutlet UILabel *descLabel;
@property (weak, nonatomic) IBOutlet UIButton *leftBtn;
@property (weak, nonatomic) IBOutlet UIButton *rightBtn;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@property (nonatomic, assign) int index;
@property (nonatomic, strong) NSArray *imageDicts;

@end

@implementation ViewController

- (NSArray *)imageDicts{
if (!_imageDicts) {
_imageDicts = [NSArray arrayWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:@"imageDate.plist" ofType:nil]];
}
return _imageDicts;
}

- (IBAction)clickLeftBtn:(UIButton *)sender {
self.index --;
[self clickBtn];
}
- (IBAction)clickRightBtn:(UIButton *)sender {
self.index ++;
[self clickBtn];
}

- (void)clickBtn{
self.topLabel.text = [NSString stringWithFormat:@"%d/%d", self.index+1, self.imageDicts.count];
self.descLabel.text = self.imageDicts[self.index][@"description"];
self.imageView.image = [UIImage imageNamed:self.imageDicts[self.index][@"name"]];

self.leftBtn.enabled = (self.index != 0);
self.rightBtn.enabled = (self.index != 4);

}

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end
0%