分类 生活 下的文章

2.1. 与 Objective-C API 交互

2.互用性

2.1. 与 Objective-C API 交互

互用性是让 Swift Objective-C 相接合的一种特性,使你能够在一种语言编写 的文件中使用另一种语言。当你准备开始把 Swift 融入到你的开发流程中时,你 应该懂得如何利用互用性来重新定义并提高你写 Cocoa 应用的方案。

互用性很重要的一点就是允许你在写 Swift 代码时使用 Objective-C API 接 口。当你导入一个 Objective-C 框架后,你可以使用原生的 Swift 语法实例化它 的 Class 并且与之交互。

初始化(Initialization)

为了使用 Swift 实例化 Objective-C Class,你应该使用 Swift 语法调用它的 一个初始化器。当 Objective-C init方法变化到 Swift,他们用 Swift 初始化 语法呈现。“init”前缀被截断当作一个关键字,用来表明该方法是初始化方法。那些 以“initWith”开头的 init 方法,“With”也会被去除。从“init”或者“initWith”中分离出来 的这部分方法名首字母变成小写,并且被当做是第一个参数的参数名。其余的每一 部分方法名依次变味参数名。这些方法名都在圆括号中被调用。

举个例子,你在使用 Objective-C 时会这样做: 

//Objective-C
UITableView *myTableView = [[UITableView alloc]
initWithFrame:CGRectZero style:UITableViewStyleGrouped];

 

Swift 中,你应该这样做: 

//Swift
let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)

 

你不需要调用 alloc,Swift 能替你处理。注意,当使用 Swift 风格的初始化函数 的时候,“init”不会出现。

你可以在初始化时显式的声明对象的类型,也可以忽略它,Swift 能够正确判断对 象的类型。 

//Swift
let myTextField = UITextField(frame: CGRect(0.0, 0.0, 200.0, 40.0))

这里的UITableViewUITextField对象和你在 Objective-C 中使用的具有相同的功 能。你可以用一样的方式使用他们,包括访问属性或者调用各自的类中的方法。

为了统一和简易,Objective-C 的工厂方法也在 Swift 中映射为方便的初始化方 法。这种映射能够让他们使用同样简洁明了的初始化方法。例如,在 Objective-C 中你可能会像下面这样调用一个工厂方法: 

//Objective-C
UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0];

 

Swift 中,你应该这样做: 

 

//Swift
let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)

 

访问属性(Accessing Properties)
Swift 中访问和设置 Objective-C 对象的属性时,使用点语法 

///Swift
myTextField.textColor = UIColor.darkGrayColor()
myTextField.text = "Hello world"
if myTextField.editing {
myTextField.editing = false
}

get set 属性时,直接使用属性名称,不需要附加圆括号。注意, darkGrayColor 后面附加了一对圆括号,这是因为 darkGrayColor UIColor 的一个类 方法,不是一个属性。
Objective-C 中,一个有返回值的无参数方法可以被作为一个隐式的访问函 数,并且可以与访问器使用同样的方法调用。但在 Swift 中不再能够这样做了, 只有使用@property 关键字声明的属性才会被作为属性引入。

方法(Working with Methods)
Swift 中调用 Objective-C 方法时,使用点语法。

Objective-C 方法转换到 Swift 时,Objective-C selector的第一部分将会 成为方法名并出现在圆括号的前面,而第一个参数将直接在括号中出现,并且没有 参数名,而剩下的参数名与参数则一一对应的填入圆括号中。

举个例子,你在使用 Objective-C 时会这样做:

Swift 中,你应该这样做:

如果你调用一个无参方法,仍必须在方法名后面加上一对圆括号

page10image10560 page10image10984 page10image11576 page10image12160 page10image14560 page10image14984 page10image15576 page10image16160 page10image19240 page10image19832 page10image20576 page10image21168 page10image21592 page10image22016 page10image22176 page10image22600  page10image22920

//Objective-C
[myTableView insertSubview:mySubview atIndex:2];

page10image23752 page10image23912 page10image24072 page10image24496 page10image24656

//Swift

myTableView.insertSubview(mySubview, atIndex: 2)

page10image29472 page10image29896 page10image30056 page10image30480  page10image30800

//Swift
myTableView.layoutIfNeeded()

page10image31552 page10image31712 page10image31872 page10image32296

id 兼容性(idCompatibility)

Swift 包含一个叫做AnyObject的协议类型,表示任意类型的对象,就像 Objective-C 中的id一样。AnyObject协议允许你编写类型安全的 Swift 代码同时 维持无类型对象的灵活性。因为AnyObject协议保证了这种安全,Swift id 对象 导入为 AnyObject
举个例子,跟
id 一样,你可以为AnyObject类型的对象分配任何其他类型的对 象,你也同样可以为它重新分配其他类型的对象。

你也可以在调用 Objective-C 方法或者访问属性时不将它转换为具体类的类型。 这包括了 Objcive-C 中标记为 @objc 的方法。

然而,由于直到运行时才知道 AnyObject 的对象类型,所以有可能在不经意间写出 不安全代码。另外,与 Objective-C 不同的是,如果你调用方法或者访问的属性 AnyObject 对象没有声明,将会报运行时错误。比如下面的代码在运行时将会报 出一个 unrecognized selector error 错误:

但是,你可以通过 Swift optinals 特性来排除这个 Objective-C 中常见的错 误,当你用AnyObject对象调用一个 Objective-C 方法时,这次调用将会变成一次 隐式展开 optional(implicitly unwrapped optional)的行为。你可以通过 optional 特性来决定 AnyObject 类型的对象是否调用该方法,同样的,你可以把这种特性 应用在属性上。 举个例子,在下面的代码中,第一和第二行代码将不会被执行因为 length 属性和 characterAtIndex:方法不存在于 NSDate 对象中。myLength常量会被推测成可选的 

Int 类型并且被赋值为 nil。同样你可以使用 if-let 声明来有条件的展开这个方法 的返回值,从而判断对象是否能执行这个方法。就像第三行做的一样。

对于 Swift 中的强制类型转换,从 AnyObject 类型的对象转换成明确的类型并不 会保证成功,所以它会返回一个可选的值。而你需通过检查该值的类型来确认转换 是否成功。

当然,如果你能确定这个对象的类型(并且确定不是 nil),你可以添加 as 操作符 强制调用。

使用 nil(Working with nil)

Objective-C 中,对象的引用可以是值为 NULL 的原始指针(同样也是 Objective- C 中的 nil)。而在 Swift 中,所有的值包括结构体与对象的引用都被保证为非 空。作为替代,你将这个可以为空的值包装为 optional type。当你需要宣告值为空 时,你需要使用 nil。你可以在 Optionals 中了解更多。

因为 Objective-C 不会保证一个对象的值是否非空,Swift 在引入 Objective-C API 的时候,确保了所有函数的返回类型与参数类型都是 optional,在你使用 Objective-C API 之前,你应该检查并保证该值非空。 在某些情况下,你可能绝 

对确认某些 Objective-C 方法或者属性永远不应该返回一个 nil 的对象引用。为了 让对象在这种情况下更加易用,Swift 使用 implicitly unwrapped optionals 方法引 入对象, implicitly unwrapped optionals 包含 optional 类型的所有安全特性。此 外,你可以直接访问对象的值而无需检查 nil。当你访问这种类型的变量时, implicitly unwrapped optional 首先检查这个对象的值是否不存在,如果不存在, 将会抛出运行时错误。

扩展(Extensions)

Swift 的扩展和 Objective-C 的类别(Category)相似。扩展为原有的类,结构和 枚举丰富了功能,包括在 Objective-C 中定义过的。你可以为系统的框架或者你 自己的类型增加扩展,只需要导入合适的模块并且保证你在 Objective-C 中使用 的类、结构或枚举拥有相同的名字。

举个例子,你可以扩展 UIBezierPath 类来为它增加一个等边三角形,这个方法只需 提供三角形的边长与起点。

page13image5368 page13image6696

//Swift
extension UIBezierPath {
    convenience init(triangleSideLength: Float, origin: CGPoint) {
       self.init()
       let squareRoot = Float(sqrt(3))
       let altitude = (squareRoot * triangleSideLength) / 2
       moveToPoint(origin)
       addLineToPoint(CGPoint(triangleSideLength, origin.x))
       addLineToPoint(CGPoint(triangleSideLength / 2, altitude))
       closePath()

} }

你也可以使用扩展来增加属性(包括类的属性与静态属性)。然而,这些属性必须
是通过计算才能获取的,扩展不会为类,结构体,枚举存储属性。下面这个例子为

类增加了一个叫 的属性。

 

CGRect

area

//Swift
extension CGRect {
    var area: CGFloat {
    return width * height
    }
}
let rect = CGRect(x: 0.0, y: 0.0, width: 10.0, height: 50.0)
let area = rect.area
// area: CGFloat = 500.0

 

你同样可以使用扩展来为类添加协议而无需增加它的子类。如果这个协议是在 Swift 中被定义的,你可以添加 comformance 到它的结构或枚举中无论它们在 Objective-C 或在 Swift 中被定义。
你不能使用扩展来覆盖 Objective-C 类型中存在的方法与属性。 闭包(Closures)
Objective-C 中的blocks会被自动导入为 Swift 中的闭包。例如,下面是一个 Objective-C 中的 block 变量:

而它在 Swift 中的形式为

Swift 的闭包与 Objective-C 中的 blocks 能够和睦相处,所以你可以把一个 Swift 闭包传递给一个把 block 作为参数的 Objective-C 函数。Swift 闭包与函数 具有互通的类型,所以你甚至可以传递 Swift 函数的名字。

闭包与 blocks 语义上想通但是在一个地方不同:变量是可以直接改变的,而不是 像 block 那样会拷贝变量。换句话说,Swift 中变量的默认行为与 Objective-C __block 变量一致。

 

//Objective-C
void (^completionBlock)(NSData *, NSError *) = ^(NSData *data, NSError *error) {/* … */}

page14image18272 page14image18696 page14image18856 page14image19280  page14image19600

//Swift
let completionBlock: (NSData, NSError) -> Void = {data, error in /* … */}
page15image1608
比较对象(Object Comparison)
当比较两个 Swift 中的对象时,可以使用两种方式。第一种,使用(==),判断 两个对象内容是否相同。第二种,使用(===),判断常量或者变量是否为同一个对 象的实例。
Swift Objective-C 一般使用 == === 操作符来做比较。Swift == 操作 符为源自 NSObject 的对象提供了默认的实现。在实现 == 操作符时,Swift 调 用 NSObject 定义的 isEqual: 方法。

NSObject 类仅仅做了身份的比较,所以你需要在你自己的类中重新实现 isEqual: 方法。因为你可以直接传递 Swift 对象给 Objective-C API,你也应该为这些 对象实现自定义的 isEqual: 方法,如果你希望比较两个对象的内容是否相同而不 是仅仅比较他们是不是由相同的对象派生。

作为实现比较函数的一部分,确保根据 Object comparison 实现对象的 hash 属 性。更进一步的说,如果你希望你的类能够作为字典中的键,也需要遵从 Hashable 协议以及实现 hashValues 属性。

Swift 类型兼容性(Swift Type Compatibility)

当你定义了一个继承自NSObject或者其他 Objective-C 类的 Swift 类,这些类都 能与 Objective-C 无缝连接。所有的步骤都有 Swift 编译器自动完成,如果你从 未在 Objective-C 代码中导入 Swift 类,你也不需要担心类型适配问题。另外一 种情况,如果你的 Swift 类并不来源自 Objectve-C 类而且你希望能在 Objecive- C 的代码中使用它,你可以使用下面描述的 @objc 属性。

@objc 可以让你的 Swift API Objective-C 中使用。换句话说,你可以通过在任 何 Swift 方法、类、属性前添加@objc,来使得他们可以在 Objective-C 代码中使 用。如果你的类继承自 Objective-C,编译器会自动帮助你完成这一步。编译器还会 在所有的变量、方法、属性前加 @objc,如果这个类自己前面加上了@objc关键 字。当你使用@IBOutlet,@IBAction,或者是@NSManaged 属性时,@objc 也会自动加在 前面。这个关键字也可以用在 Objetive-C 中的 target-action 设计模式中,例 如,NSTimer 或者 UIButton

当你在 Objective-C 中使用 Swift API,编译器基本对语句做直接的翻译。例如, Swift API func playSong(name: String)会被解释为

*)name。然而,有一个例外:当在 Objective-C 中使用 Swift 的初始化函数,编译 器会在方法前添加“initWith”并且将原初始化函数的第一个参数首字母大写。例如, 这个 Swift 初始化函数 init (songName: String, artist: String 将被翻译为 (instancetype)initWithSongName:(NSString *)songName artist:(NSString *)artist Swift 同时也提供了一个@objc关键字的变体,通过它你可以自定义在 Objectiv-C 中转换的函数名。例如,如果你的 Swift 类的名字包含 Objecytive-C 中不支持的 字符,你就可以为 Objective-C 提供一个可供替代的名字。如果你给 Swift 函数 提供一个 Objecytive-C 名字,要记得为带参数的函数添加(:)
page16image5400

- (void)playSong:(NSString

page16image6472

page16image7032 page16image7192 page16image7776

page16image8784 page16image10272
page16image17544 page16image17968 page16image18560 page16image19728 page16image21056

//Swift
@objc(Squirrel)
class Белка {
    @objc(initWithName:)
    init (имя: String) { /*...*/ }
    @objc(hideNuts:inTree:)
    func прячьОрехи(Int, вДереве: Дерево) { /*...*/ }

}

当你在 Swift 类中使用@objc(<#name#>)关键字,这个类可以不需要命名空间即可在 Objective-C 中使用。这个关键字在你迁徙 Objecive-C 代码到 Swift 时同样也非 常有用。由于归档过的对象存贮了类的名字,你应该使用@objc(<#name#>)来声明与 旧的归档过的类相同的名字,这样旧的类才能被新的 Swift 类解档。

Objective-C 选择器(Selectors)

一个 Objective-C 选择器类型指向一个 Objective-C 的方法名。在 Swift 时代, Objective-C 的选择器被Selector结构体替代。你可以通过字符串创建一个选择 器,比如 let mySelector: Selector = “tappedButton:”。因为字符串能够自动转换为 选择器,所以你可以把字符串直接传递给接受选择器的方法。page16image35192 page16image36520 page16image37104 page16image37696 page16image38440 page16image39032

//Swift
import UIKit
class MyViewController: UIViewController {
    let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))
    init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {
super.init(nibName: nibName, bundle: nibBundle)
    myButton.targetForAction("tappedButton:", withSender: self)
}
func tappedButton(sender: UIButton!) {
    println("tapped button")

}

}

注意: performSelector:方法和相关的调用选择器的方法没有导入到 Swift 中因为 它们是不安全的。
如果你的 Swift 类继承自 Objective-C 的类,你的所有方法都可以用作 Objective-C 的选择器。另外,如果你的 Swift 类不是继承自 Objective-C,如果 你想要当选择器来使用你就需要在前面添加@objc 关键字,详情请看 Swift 类型兼 容性。 

 

1.1.基本设置

重要事项

这篇文章初步介绍了在开发中用到的 API 或技术。苹果公司提供这些信息来帮助 您规划本文所说明的技术和接口以用于苹果的产品上。这些信息会改变,并且根据 这篇文章所实现的软件应该在最新的操作系统并根据最新的文档测试。本文档的新 版本,可能在未来通过技术和 API seeds 版本来提供

Swift 被设计用来无缝兼容 Cocoa Objective-C 。在 Swift 中,你可以使用 Objective-C API(包括系统框架和你自定义的代码),你也可以在 Objective- C 中 使用 Swift API。这种兼容性使 Swift 变成了一个简单、方便并且强大的 工具集成到你的 Cocoa 应用开发工作流程中。

这篇指南包括了三个有关兼容性的重要方面方便你更好地利用来开发 Cocoa 应 用:

  •   互用性 使你将 Swift Objective-C 相接合,允许在 Objective-C 中使用 Swift Class 并且当你在写 Swift 代码时利用熟悉的 Cocoa ClassPatternPractice
  •   混合和匹配 允许你创建结合了 Swift Objective-C 文件的混合语言应用,他们 能更彼此进行通信。
  •   迁移 由于以上两点,从已经存在的 Objective-C 代码迁移到 Swift 是非常简单 的,使得用最新的 Swift 特性代替你的 Objective-C 应用部分内容成为了可能。 在你开始学习这些特性前,你需要对如何建立 Swift 环境来访问 Cocoa 系统框架 有个大体了解。 

    建立你的 Swift 环境
    为了开始体验在 Swift 中访问 Cocoa 框架,使用 Xcode 的一个模板来创建一个

    基于 Swift 应用。
    在 Xcode 中创建一个 Swift 项目

    1.选择 File > New > Project > (iOS or OS X) > Application > your template of choice

    2.点击 Language 弹出菜单并选择 Swift

     

    点击 Language 弹出菜单并选择 Swift

    Swift 项目的结构几乎和 Objective-C 项目一模一样,只有一个重要的区别:Swift 没有头文件。在实现和接口之间没有显示的划分,所以一个特定类中的所有信息都 存储在单独的.swift 文件中。
    现在开始,你可以开始体验在
    app delegate 中写 Swift 代码,或者你可以通过选择 File > New > File > (iOS or OS X) > Other > Swift 来创建一个 Swift 类。 

    理解 Swift 导入过程
    在你建立 Xcode 项目后,你可以在 Swift 里导入任意用 Objective-C 来工作的

    Cocoa 平台框架。

    任意 Objective-C 的框架(或 C 类库)将作为一个 module,能直接导入到
    Swift 中。这些包括了所有 Objective-C 系统框架比如 FoundationUIKit SpriteKit,就像系统支持公共 C 类库。举个例子,想导入 Foundation,只要简单 地添加 import 语句到你写的 Swift 文件的顶部。

    SWIFT

        import Foundation
    

    这个 import 导入了所有 Foundation API,包括NSDate,NSURL, NSMutableData,并且他们的所有方法、属性和类别都可以在 Swift 中直接使用。

    导入过程是非常简洁的。Objective-C 框架在头文件中申明 API。在 Swift 中,那 些头文件被编译成 Objective-C module,接着被导入到 Swift 作为 Swift API。导入决定了 Objective-C Function,Class,Method Type 如何在 Swift 中出现。对于 Function Method,这个过程影响他们的参数和返回值。 导入过程可以做下面这些事情:

    •   重映射确定的 Objective-C 类型到 Swift 中的同等类型,就像 id AnyObject
    •   重映射确定的 Objective-C 核心类型到 Swift 中的替代类型, 就像NSStringString
    •   重映射确定的 Objective-C 概念到 Swift 中相匹配的概念,如pointersoptionals 在互用性章节,你将会了解到更多关于这些映射如何在你的 Swift 代码进行取 舍。 导入 Swift 的模型到 Objective-C 和从 Objective-C 导入 Swift 是非常相 似的。Swift 申明它的 API,比如一个框架作为 Swift modules。同时这些 Swift modules 会生成 Objective-C 的头文件。这些头文件可以映射回 Objective-C API 中。一些 Swift API 不映射回 Objective-C 因为他们取舍了语言特性发 现这些在 Objective-C 中不可用。关于在 Objective-C 中使用 Swift 的更多特 性,请参看在同一项目中使用 Swift Objective-C。 

    注意
    你不能直接把
    C++ 代码导入 Swift。解决办法是为 C++ 代码创建一个

    Objective-C 或者 C 的封装。 

Photoshop快捷键

关于photoshop,我总得说些什么,在过去的日子里,我接触了各种各样的软件,但终究最爱并且能玩得转的只有photoshop。

不过到目前为止我尚未成为高手,可以说路还有很长。平常我习惯逛老外的网站,看了不少很不错的文章,我总结了一下分享出来,希望对大家有帮助。这里主要谈谈关于PS的快捷键问题,一般高手都习惯用快捷键工作,而且我觉得用快捷键的人显得更帅。PS的快捷键很多,基本布满了整个键盘,但同时很多快捷键设计得不合理,我在老外的一篇文章学到,把F1直到F12设置成自己常用的快捷键,这个想法真的太好。首先F1到F12的12个键,在工作中基本不会用到,而且作为单键的快捷键取代PS里中的三键的快捷键,可以简化工作,甚至别人看不懂你的快捷键分布,令人对你产生高手的错觉。

我把我总结出来的键位写出来,当然,我是以自己UI设计师的使用习惯设置,你也可以自己自定义,总之这个做法非常有用,相信我,你的PS速度会提升几个档次。但有一点要注意的是,由于键位的改变,自己要花时间适应的同时,其他人会不知道你的键盘是不是出故障了。

设置快捷键的功能在:编辑>键盘快捷键。

F1:画布水平翻转。本来这个功能是在:图像>旋转画布>水平翻转画布,对于日常的设计工作上不常用,但在绘画上却很经用,水平翻转使你更了解自己的作品,甚至了解你的审美观。就像你觉得镜子里的自己特别顺眼,但别人看你的影响和你镜子里的影响确实水平翻转的,所以当你用两面镜子重复反射时就可以看到真实的自己。同理,通过翻转画布,可以使你脱离你固有的审
美,所以插画师经常边画边翻转画布。

F2:图像另存为。本来这个功能在哪就不说了,快捷键为:Ctrl+Shift+S。可见,Photoshop中很多三个按键组合的快捷键,按起来略不便,有了这个就可以体验一键保存文件了。

F3:向后退一步。本来这个功能的快捷键为:Ctrl+Alt+Z。这个组合键太经常用,却被设计得那么繁琐。

F4:向前进一步。本来这个功能的快捷键为:Ctrl+Shift+Z。和上面那个F3一样,现在通过操作简单的F3+F4,可以令编辑工作变得更轻松。

F5:取消选区。本来这个功能的快捷键为:Ctrl+D。选区的意义就不多说了,一键取消选区很常用。

F6:反选。本来这个功能的快捷键为:Ctrl+Shift+I。这个也不多说了,作图常用。

F7:显示/隐藏参考线。本来这个功能是在:视图>显示>参考线。这个确实要重点说说,尤其对UI设计师来说,作图就必需精确到每一像素,画图形切忌在没规划就下手,良好的习惯是先配合网格功能作出参考线,作用就是规范图形的尺寸范围。但很多设计师没有这个习惯也是难怪的,因为这种步骤略显繁琐。

F8:显示/隐藏网格。本来这个功能是在:视图>显示>网格。这个也是很重要功能,但却一直被忽视。网格是使图形精细化的最好工具,能使图形变得更完美。在一些UI手册中经常说到的一点是怎么画出“完美像素”,就是通过网格做出来的。

F9:100%显示画布。对于画布的缩放,方法有很多。例如快捷键:Ctrl+减号/加号,或者Alt+鼠标滚轮,或者面板里的百分百按钮。而F9键则只负责100%显示,可以迅速恢复视图实际像素。

F10:全屏显示画布。这个键和上面的意义差不多,不多说。

F11:剪切蒙版。蒙版这玩意,对初学者来说有点难理解,尤其PS里有:快速蒙版,图层蒙版,剪切蒙版三种,初学者会傻傻分不清楚,这里就不对这个概念累赘了。剪切蒙版对于UI很常用,它用于利用图层的形状关系去限制图像的显示区域,能使图形保持在良好的显示中。

F12:快速保存图层。这个功能很多人没听过,而这个功能我在之前的文章里提过。举个例子:你新建了一个宽高都为100px文件,然后新建图层,在上面画了一个直径为50px的圆,再新建图层,在上面画一个边长50px的矩形。那我要你单独把圆保存出来并且不要空白怎么办?过去的UI做法是:先隐藏底层和矩形的图层,再用参考线和网格,标识好圆的边沿,再用裁剪工具进行裁
剪,最后把圆另存为。是不是很麻烦,假如圆形是带有阴影或者外发光什么的,就更难裁剪。其实这个F12就是一个老外发明的切图动作,一键切图并保存,省去了上面所说的所有步骤,无论图层带有任何样式,或者多个图层保存甚至分组保存,它都可以快速完成,这个UI设计师来说,是天大的福音。
这个脚本叫:Retinize It,意思是专门为retina设备准备的切图工具,作者官网:retinize,而我把脚本修改精简过,能自动保存到桌面。下载我修改过的动作:Retinize It。

在使用以上快捷键前,请看看下面的注意事项:

为了精细画网格,请把网格密度调为64px。编辑>首选项>参考线、网格和切片。在网格区域那里,把网格线间隔调为64,把子网格也调成64,后面的单位选择像素。
请保持标尺的开启,并且把单位调成像素,方便拉出参考线。视图>标尺。
为了对齐图形,请打开技能参考线。视图>显示>智能参考线。
为了避免PS的出错,请更改缓存盘。编辑>首选项>性能。勾掉C盘,选择其他盘。
F12键的脚本,我是在Win7下的默认用户设置,所以保存桌面的路径只使用与Win7并且是默认用户,XP或者Win8用户请自己修改动作的保存路径,怎么修改请自行百度。

电视剧《湄公河大案》完结有感

刚刚从CNTV 上看完,没记错的话,这个电视剧应该是在三天前就在CCTV 1 黄金档播出了大结局。好吧,我承认这个电视剧有很多吐槽的槽点,比如说部分情节特别的假(警察跟踪,那个近,没法说,不被发现才怪),当然可能最为严重的是剧情严重偏离现实,这剧今本上完全是用着湄公河这个词,完完全全虚构了剧情。

But,我们都有病,这剧却也是挺虐心。

我几乎是一集没差的看完,偶尔晚上准时在电视机面前看,多数都是夜深人静的时候在CNTV上看,今天终于看完了。

若是好剧,虐心一生

两个人的情感纠葛,有媳妇,有女朋友,最令人揪心的是她不理解你,生你的气,无论你怎么做,只要说错一丁点,你就Gmae Over了

剧情中已故的人,代表正义的人死去,这边是上等的虐心

感谢


因为种种原因,导致我对我的这个不知道该怎么定义的站点的样式不怎么满意,从simple love 再到默认主题, 反反复复改了n多次,终于在刚才,我无意间发现了一个非常棒的主题,这个便是老赵茶室,特别感谢Mr.Zhao非常无私的把自己的主题分享出来,非常感谢Mr.Zhao的这么有情怀的主题 :p

2025 年 5 月
 1234
567891011
12131415161718
19202122232425
262728293031  

广告

分类

近期评论

标签

历史上的今天

归档