当前位置: 首页 > 编程日记 > 正文

如何用Swift实现一个好玩的弹性动画

本文由CocoaChina译者浅夏@旧时光翻译自Raywenderlich

原文:How To Create an Elastic Animation with Swift


original.gif每个像样的iOS应用程序一定会有自定义元素、自定义UI以及自定义动画等等很多自定义的东西。

假如你想让你的应用脱颖而出,你必须花费一些时间为你的应用增添一些独特的元素,这些元素将会使你的应用耳目一新。

在这个教程中,你将学会如何创建一个自定义的文本框视图(text field view),当你点击这个文本框时,它的边框会有一个令人愉悦的弹性动画,效果如下图:

在学习的过程中,你讲会用到许多有趣的API:

  • CAShapeLayer

  • CADisplayLink

  • UIView spring animations

  • IBInspectable

开始吧!


首先下载启动项目ElasticUI-Starter。

这个工程是基于Single View Applicetion模板的应用,创建过程是iOS\Application\Single View Application。目前在container view里有两个文本框和一个按钮

001.png

你的目标是当用户点击时给它们一个伸缩的弹性动画。怎么实现这个功能?

002.jpg

这个技术是很简单的,你将会用到四个control point views和一个CAShapeLayer对象,然后使用UIView的spring animations动画使control points做动画。当它们

在动画过程中时,你要重绘它们位置周围的形状。

注意:如果你不熟悉CAShapeLayer这个类,请参阅 这里 Scott Gardner写的一篇很棒的教程,能够迅速的帮你入门。

这个动画看起来似乎有点复杂,但不用担心,它比你想象中要容易。

创建一个基本的弹性视图

首先,你要创建一个基本的弹性视图,并且把它作为子视图嵌入到UITextfield中,然后激活这个视图并控制弹性动画。

在工程的导航器上,选中ElasticUI文件夹右击选择新建文件,然后选择iOS/Source/Cocoa Touch Class模板,然后点击下一步,命名这个类名为ElasticView,它的父

类选择UIView ,语言选择swift。单击Next,然后选择默认位置来创建存储文件相关的新类。

最重要的是,你需要创建4个控制点和一个CAShapeLayer对象。添加下面的代码,最终得到的类定义:

import UIKitclass ElasticView: UIView {private let topControlPointView = UIView()private let leftControlPointView = UIView()private let bottomControlPointView = UIView()private let rightControlPointView = UIView()private let elasticShape = CAShapeLayer()override init(frame: CGRect) {super.init(frame: frame)setupComponents()}required init(coder aDecoder: NSCoder) {super.init(coder: aDecoder)setupComponents()}private func setupComponents() {}
}

这些视图和图层能够立即创建。setUpComponents()是一个配置方法,它会在所有的初始化方法中调用。现在你要设法实现它。

在setUpComponents()方法中增添如下代码:

elasticShape.fillColor = backgroundColor?.CGColor
elasticShape.path = UIBezierPath(rect: self.bounds).CGPath
layer.addSublayer(elasticShape)

以上是配置图形图层,设置它的填充色和ElasticView的背景色一样,填充的路径的和视图的边界一样。最后把它添加到图层结构上。

接下来,在setUpComponents()方法的最后添加以下代码:

for controlPoint in [topControlPointView, leftControlPointView,bottomControlPointView, rightControlPointView] {addSubview(controlPoint)controlPoint.frame = CGRect(x: 0.0, y: 0.0, width: 5.0, height: 5.0)controlPoint.backgroundColor = UIColor.blueColor()
}

在你的视图上添加了四个控制点。为了更好地调试,我们把控制点的背景色改成了蓝色,这样容易在模拟器里看到它们。在教程的最后部分你会移除这段代码。

你需要把这些控制点分别放到上边界中心、下边界中心、左边界中心和右边界中心。这样做是为了,当你让它们离开视图的时候,你可以利用它们的位置在你的CAShapeLayer对象上绘制新的路径。

这个操作会频繁进行,因此创建一个新的函数来是实现它。在ElasticView.swift文件中中添加以下代码:

private func positionControlPoints(){topControlPointView.center = CGPoint(x: bounds.midX, y: 0.0)leftControlPointView.center = CGPoint(x: 0.0, y: bounds.midY)bottomControlPointView.center = CGPoint(x:bounds.midX, y: bounds.maxY)rightControlPointView.center = CGPoint(x: bounds.maxX, y: bounds.midY)
}

这个函数在视图边界上将每个控制点移到正确的位置。

在setUpComponents()函数调用之后调用新的函数:

positionControlPoints()

在实现动画之前,你可以在storyboard添加一个View把玩一下,这样你就可以知道ElasticView类是怎么工作的。

打开Main.storyboard文件,拉一个UIView对象到Controller的视图上,设置它的Custom Class为ElasticView。不用在意它的位置,只要保证它在屏幕内就可以,接下来你就可以看到将要发生的事。

003.png

编译并运行程序:

004.png

看上图,四个小的蓝色正方形--它们就是你在setupComponents函数中添加的控制点视图。现在为了得到弹性效果,你将会在CAShapeLayer对象上用它们创建一个路径。

使用UIBezierPath类绘制图形


在你探究接下来的一系列步骤之前,想象下如何绘制2D图形--具体来说,你依赖画线,特别是直线和曲线。在画任何线之前,不论是直线还算复杂的曲线,你需要至少确定起点和终点,或者更多的位置点。

这些点全是CGponit类,你必须确认这些点在当前坐标系下的X坐标和Y坐标。

如果你想要矢量图形,例如正方形、多边形或者复杂的弯曲图形,会更复杂。

想要模拟弹性效果,你要画一个二次贝塞尔曲线(Quadratic Bézier Curves),看起来像个长方形,但是这个长方形的每个边都有一个控制点,并且它提供了一个有弹性效果的曲线。

贝塞尔曲线是以Pierre Bézier的名字命名的,他是一位法国的工程师,在CAD/CAM系统下从事展现曲线的工作。下面是贝塞尔曲线的样式:

32.png

蓝色的实心圆是控制点,它们是你之前创建的4个视图,红色的点是长方形的顶点。

注意:苹果公司对 UIBezierPath类 的文档介绍已经很深入了,如果你想深入了解如何创建一个路径,它还是值得一看的。

现在是时候把理论付诸实践了。在ElasticView.swift文件中添加下面的方法:

private func bezierPathForControlPoints()->CGPathRef {// 1let path = UIBezierPath()// 2let top = topControlPointView.layer.presentationLayer().positionlet left = leftControlPointView.layer.presentationLayer().positionlet bottom = bottomControlPointView.layer.presentationLayer().positionlet right = rightControlPointView.layer.presentationLayer().positionlet width = frame.size.widthlet height = frame.size.height// 3path.moveToPoint(CGPointMake(0, 0))path.addQuadCurveToPoint(CGPointMake(width, 0), controlPoint: top)path.addQuadCurveToPoint(CGPointMake(width, height), controlPoint:right)path.addQuadCurveToPoint(CGPointMake(0, height), controlPoint:bottom)path.addQuadCurveToPoint(CGPointMake(0, 0), controlPoint: left)// 4return path.CGPath
}

在上面的函数中的代码有一点复杂,所以下面是分步解析一下,方便大家理解:

1、创建一个UIBezierPath类对象来保存你的形状。

2、提取四个控制点的位置分别为top、left、bottom和right四个常量。使用presentationLayer的原因是为了在控制点视图动画期间得到它们变化中的的位置。

3、通过长方形的顶点和4个控制点,绘制曲线,来创建路径。

4、返回路径的CGPathRef,这就是我们期望的图层形状。

当控制点在动画过程中的时候,你需要调用这个方法,因为它可以一直在重绘新的图形。到底该怎么做呢?

QQ截图20150826142038.png

CADisplayLink 对象是一个定时器,它允许应用程序的活动和显示器的刷新率同步。你只需要添加一个target和一个action,那么当屏幕的内容更新的时候,action方法将会被调用。

它是一个很完美的机会去重绘你的路径并且更新你的图形图层。

首先,添加一个每次更新都必须调用的方法:

func updateLoop() {elasticShape.path = bezierPathForControlPoints()
}

然后,在ElasticView.swift类中创建一个CADisplayLink对象名为displayLink的变量,代码如下:

private lazy var displayLink : CADisplayLink = {let displayLink = CADisplayLink(target: self, selector: Selector("updateLoop"))displayLink.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes)return displayLink
}()

这个懒加载模式的变量就是意味着这个对象当你需要用的时候它才会被创建。每次屏幕更新的时候,就会调用updateLoop()函数。你需要开始或启用link,因此增加下面的代码:

private func startUpdateLoop() {displayLink.paused = false
}private func stopUpdateLoop() {displayLink.paused = true
}

你已经做好了无论什么时候去移动控制点的,然后去画一个新路径的所有准备工作,那么接下来就是移动它们了。

UIView Spring Animations


苹果公司是很擅长添加新的特性的,当iOS系统新版本发布的时候,spring animations 是最近版本包含的众多特性之一,它可以很容易的使你的应用增加令人吃惊的元素。它允许你给动画元素添加自定义的阻尼运动和初始速度,使动画更特殊和有弹性。

注意:如果你想精通动画,点击这里查看iOS Animations by Tutorials。

在ElasticView.swift 中添加以下代码,迅速获得控制点的运动轨迹:

func animateControlPoints() {  //1let overshootAmount : CGFloat = 10.0// 2UIView.animateWithDuration(0.25, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 1.5,options: nil, animations: {// 3self.topControlPointView.center.y -= overshootAmountself.leftControlPointView.center.x -= overshootAmountself.bottomControlPointView.center.y += overshootAmountself.rightControlPointView.center.x += overshootAmount},completion: { _ in// 4UIView.animateWithDuration(0.45, delay: 0.0, usingSpringWithDamping: 0.15, initialSpringVelocity: 5.5,options: nil, animations: {// 5self.positionControlPoints()},completion: { _ in// 6self.stopUpdateLoop()})})
}

下面是按步骤分解:

1、overshootAmount是控制点移动的偏移量。

2、在spring animation 动画中Block块包含的即将到来的UI变化将会持续0.25秒。假如你不熟悉spring animation 但是擅长物理学,你可以参阅UIView类的官方文档了解damping变量和velocity变量的详细说明。对于并非专家的普通人来说,仅仅知道这两个变量是控制动画如何伸缩的就可以。通过多次修改填写这两个变量的数值来找到我们要的动画效果是很正常的。

3、上下左右移动控制点,将会产生动画。

4、创建另一个spring animation 动画使视图还原。

5、重置控制点的位置——这也是一个动画。

6、动画结束的时候暂停displaylink更新。

目前为止,还没有调用animateControlPoints函数。我们自定义控制的目的是一旦点击视图,就会用动画产生。所以我们最好在touchedBegan函数中调用上面的函数。添加的代码如下:

override func touchesBegan(touches: Set, withEvent event: UIEvent) {startUpdateLoop()animateControlPoints()
}

运行一下工程,并且点击自定义的视图。瞧一瞧!

005.gif

重构和优化

你已经看到这个很酷的动画,但是为了使ElasticView类更加抽象你还是有很多工作要处理的。

第一个障碍是清除overshootAmount。目前,它以硬编码的方式设置值为10,但是我们希望它的值应该可以通过编程方式和Interface Builder来改变,这将是一个很大的改变。

k.jpg

@IBInspectable 是Xcode 6.0 的一个新特性,它是通过nterface Builder 设置自定义属性的很好的途径。

注意:假如你想了解更多关于@IBInspectable,请参阅Caroline Begbie写的 Modern Core Graphics with Swift。

你将使用这个令人惊叹的新特性增加一个@IBInspectable 类型的overshootAmount属性,这样你创建的每一个ElasticView类的对象可以设置成不同的值。

在ElasticView类中增添下面的代码:

@IBInspectable var overshootAmount : CGFloat = 10

在animateControlPoints() 函数中引用这个属性 ,用

let overshootAmount = self.overshootAmount

替换

let overshootAmount : CGFloat = 10.0

打开Main.storyboard,点击ElasticView,然后选择Attributes Inspector选项卡,具体如下图:

l-645x500.png

你将会看到一个新的选项,显示了自定视图的类名和一个以Overshoot A…命名的输入框。

使用 @IBInspectable声明的每一个变量,都可以在Interface Builder界面上看到一个输入框,在这个输入框里可以设置它的值。

为了看到这中现象,复制当前的ElasticView,这样你就得到两个视图,把新的视图放到原来视图的上面,如下图所示:

33.png

设置新视图和老视图Overshoot Amount属性值分别为40和20.

编译并运行程序。点击两个视图发现不同之处。正如你看到的那样,不同的动画效果依赖于你在Interface builderz中设置的Overshoot Amount值。

n.gif

改变新视图中Overshoot Amount的值为-40,看看会发生什么。你会看到4个控制点向内运动,但是背景却没有发生改变。

o.gif

你是否准备好自己去修复这个bug? 我打赌你可以做到的!

我给你一条线索:你需要在setupComponents方法中做些改变。靠自己试一下,但是如果你遇到了困难,看一下下面的解决方法。

解决方案

// You have to change the background color of your view after the elasticShape is created, otherwise the view and layer have the same color
backgroundColor = UIColor.clearColor()
clipsToBounds = false

现在你已经完成了ElasticView这个类,你可以将它嵌入不同的控件,例如文本框和按钮等等。

制作一个弹性的UITextfield


你已经建立建立了具有核心功能的弹性视图,下一步就是把它嵌入到自定义的文本框中。

右击ElasticUI工程的导航栏,然后选择New File…命令,选择iOS/Source/Cocoa Touch Class模板,然后点击下一步。

命名为ElasticTextField,父类选UITextfield,编程语言选择Swift。点击下一步然后创建。

打开ElasticTextField.swift文件,把他的内容替换成下面的代码:

import UIKitclass ElasticTextField: UITextField {// 1var elasticView : ElasticView!// 2@IBInspectable var overshootAmount: CGFloat = 10 {didSet {elasticView.overshootAmount = overshootAmount}}// 3override init(frame: CGRect) {super.init(frame: frame)setupView()}required init(coder aDecoder: NSCoder) {super.init(coder: aDecoder)setupView()}// 4func setupView() {// AclipsToBounds = falseborderStyle = .None// BelasticView = ElasticView(frame: bounds)elasticView.backgroundColor = backgroundColoraddSubview(elasticView)// CbackgroundColor = UIColor.clearColor()// DelasticView.userInteractionEnabled = false}// 5override func touchesBegan(touches: Set, withEvent event: UIEvent) {elasticView.touchesBegan(touches, withEvent: event)}
}

这里有很多逻辑,下面我们一步步分解:

1、有一个ElasticView类型的属性

2、一个叫做overshootAmount的变量,它是IBInspectable类型,所以你可以通过Interface Builder灵活的控制它的值。重写了didSet方法,你只需设置弹性视图的overshootAmount的值就可以了。

3、两个标准的初始化方法,它们都调用可setupView()方法。

4、这里是配置文本框的方法,下面让我们更详细的分解讲述它:

a.设置clipsToBounds值为false,这可以是弹性视图的大小可以超过其父视图的大小,改变UITextfield的borderStyle属性为.None,使它变成扁平的。

b.创建一个ElasticView对象并添加到当前视图上作为子视图。

c.改变当前视图的背景色为透明色,这样做的原因是让ElasticView决定视图的背景色。

d.最后,设置ElasticView的userInteractionEnabled属性为false. 否则它将会触发当前视图的Touches事件。

5、重写touchesBegan方法,并将它传递到ElasticView,使它可以做动画。

打开Main.storyboard,选中两个UITextfield对象,在Identity Inspector中把类类型从UITextField改成ElasticTextField类型。

当然,你也要删除那两个为了测试而创建的ElasticView对象。


34.png

运行程序,点击文本框,你会发现实际上它并没有用。

Last.gif

原因是在你创建ElasticView的时候,设置的只是shaperLayer的背景色为透明的,并不是视图本身。

要解决这个bug,你需要一个方法,这个方法的作用是无论何时你给视图设置背景色时,都要使视图的shape layer 设置成和视图相同的颜色。

传递背景色

因为你想用elasticShape 作为你视图的主要背景色,所以你需要在ElasticView类中重写backgroundColor方法。

在ElasticView.swift文件中增添下面的代码:

override var backgroundColor: UIColor? {willSet {if let newValue = newValue {elasticShape.fillColor = newValue.CGColorsuper.backgroundColor = UIColor.clearColor()}}
}

willSet方法在你设定值之前被调用,你会发现这个值已经被传递,然后将fillColor的颜色设置为用户选择的颜色,随后你会调用super并将其背景色设置为clearColor

运行程序,你就会得到一个很棒的弹性视图。你一定很开心。

06.gif

最后的调整
你会发现UITextfield的占位符距离它的左边界很近。你不觉得它离得太近了吗?你想自己修复这个bug吗?这次没有提示,如果你遇到了困难,看看下面的代码:

// Add some padding to the text and editing bounds
override func textRectForBounds(bounds: CGRect) -> CGRect {return CGRectInset(bounds, 10, 5)
}override func editingRectForBounds(bounds: CGRect) -> CGRect {return CGRectInset(bounds, 10, 5)
}

移除调试信息


打开 ElasticView.swift文件并且从setupComopents方法中移除下面的代码:

controlPoint.backgroundColor = UIColor.blueColor()

目前,你应该会以你已经完成的工作而骄傲。因为你已经把一个系统UITextfield控件变成了可伸缩的视图,并且创建了一个可以可以嵌套到各种UI控件的自定的可伸缩的UIView视图。

下一步


这里有一个完整项目的 链接

你有一个完整的弹性文本框,并且很多UI控件都可以应用这些技术。

您已经了解了如何使用视图位置改变自定义形状和添加反弹效果。拥有此技能,就可以说世界尽在你的掌握之中。

深入研究的话,你可以尝试各种不同的动画,增加更多的控制点,绘制一些看起来更炫酷的形状,等等。

更多关于不同动画的学习,请参阅easings.net,内容非常不错。

600.png

在你对这个技术熟悉之后,你可以尝试将BCMeshTransformView集成到你的项目。它是Bartosz Ciechanowski写的一个很好的库,你可以操作你视图上的单独的像素点

想象一下如果你可以把像素点变成各种不同的形状是多么酷的一件事情。

如何使用Swift语言创建一个弹性UI控件是一个有趣的讲解,我希望你能从这个讲解中学到一些东西。
假如你有关于如何使用Swift做动画的问题,评论或者好的想法,请在下面留言。我期待着你的回复!

相关文章:

深入探讨Python的import机制:实现远程导入模块 | CSDN博文精选

来源 | Python编程时光(ID:Python-Time)所谓的模块导入,是指在一个模块中使用另一个模块的代码的操作,它有利于代码的复用。也许你看到这个标题,会说我怎么会发这么基础的文章?与此相反。恰恰我觉得这篇文章…

吴恩达老师深度学习视频课笔记:人脸识别

什么是人脸识别:人脸验证和人脸识别的区别,如下图:One-shot learning:人脸识别所面临的挑战就是需要解决一次学习(one-shot learning)问题。这意味着在绝大多数人脸识别应用中你需要通过单单一张图像或者单单一个人脸图像就能去识…

用小白鼠喝毒药

题设:有N瓶水,其中有一瓶水有剧毒,如果小白鼠喝了会在24小时的时候死亡。 问:用多少只小白鼠能够检测出哪瓶水有剧毒? 要求:用的小白鼠数量少并且用时要短,并给出合理的过程与结论。 我的解题思…

怎样在swift中创建CocoaPods

本文由yake_099(博客)翻译自raywenderlich,作者:Joshua Greene 原文:How to Create CocoaPods with Swift 你可能对一些比较著名的开源的CocoaPods框架比较熟悉,比如Alamofire、MBProgressHUD。但是有时你…

吴恩达老师深度学习视频课笔记:神经风格迁移(neural style transfer)

什么是神经风格迁移(neural style transfer):如下图,Content为原始拍摄的图像,Style为一种风格图像。如果用Style来重新创造Content照片,神经风格迁移可以帮你生成Generated图像。深度卷积网络在学什么:如下图&#xf…

“Jupyter的杀手”:Netflix发布新开发工具Polynote

作者 | Michael Li 译者 | Rosie 编辑 | Jane 出品 | AI科技大本营(ID:rgznai100)【导读】10 月 29 日,Netflix 公开了他们内部开发的 Polynote。现如今,大型高科技公司公开其内部的工具或服务,然后受到业界…

System Center 2012 r2优点

System Center 2012System Center2012 是一个全面的管理平台,可帮助你轻松、高效地管理数据中心、客户端设备和混合云 IT 环境。为您提供了针对私有云、托管云和公有云基础结构和应用程序服务的通用管理工具集。可按照您的需求,为生产基础架构、可预期应…

Swift 闭包表达式

闭包是功能性自包含模块,可以在代码中被传递和使用。 Swift 中的闭包与 C 和 Objective-C 中的 blocks 以及其他一些编程语言中的 lambdas 比较相似。 闭包的形式主要有三种: 1. 全局函数是一个有名字但不会捕获任何值的闭包 2. 嵌套函数是一个有名字并可以捕获其封…

GNU AWK中BEGIN/END使用举例

以下是使用gnu awk将test.cpp文件拆分成两个文件a.cpp和b.cpp&#xff0c;其中b.cpp仅存放test.cpp中的数据&#xff0c;其它内容存放在a.cpp文件中。test.cpp内容如下&#xff1a; #include <stdio.h> #include <iostream> #include <string>int main() {//…

目标检测的渐进域自适应,优于最新SOTA方法

作者 | Han-Kai Hsu、Chun-Han Yao、Yi-Hsuan Tsai、Wei-Chih Hung、Hung-Yu Tseng、Maneesh Singh、Ming-Hsuan Yang译者 | 刘畅编辑 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;【导读】目标检测的最新深度学习方法依赖于大量的边界框标注信息…

讨论下IDS的绕过

自从知道dedecms自带了80sec的内置Mysqlids后&#xff0c;一直以来也没有想到绕过的办法。或者是自己mysql的根底太差了吧。于是分析dedecms源码时&#xff0c;只找模板执行&#xff0c;本地包含&#xff0c;上传等&#xff0c;完全没有想到注入存在的可能性了。 可以看看某牛的…

GCC编译选项参数介绍

gcc和g分别是gnu的c和c编译器&#xff0c;下面是整理的常用编译选项参数&#xff1a; #(1). -x: 设定文件所使用的语言&#xff0c;使文件后缀名无效&#xff0c;如下&#xff0c;执行完后生成test.o gcc -c -x c test.jpg #(2). -c: 只编译生成目标文件即*.o,只编译不链接生成…

程序员自学到底有没有用?网友们吵翻了...

最近就有个程序员吐槽说&#xff0c;自己大学没怎么听老师讲课&#xff0c;老师讲的知识要么太旧&#xff0c;要么老师不会讲&#xff0c;自己大部分时间是在网上看视频学的。引发了以下激烈的讨论。很多网友觉得&#xff0c;学校老师的代码能力不行&#xff0c;现在技术更新又…

更新 FrameWork

这里把想要改变的东西封装到FrameWork以便实现热更新&#xff0c;提一下关于BundiD 一定要一致&#xff0c;在打包的时候一定在Edit scheme —— >Run 选择Release如图&#xff1a; 因为你要跑在真机上&#xff0c;所以这个要选择Release 另外将包含你想要放出的方法类添加…

把Illustrator矢量图转化为代码:Drawscript

2019独角兽企业重金招聘Python工程师标准>>> DrawScript是一款Illustrator插件&#xff0c;可以将Illustrator的矢量图片转换成代码&#xff0c;目前免费&#xff0c;支持转换的语言有 OBJ-CCJAVASCRIPTCREATEJS/EASELJSPROCESSINGACTIONSCRIPT 3JSONRAW BEZIER PO…

必读:ICLR 2020 的50篇推荐阅读论文

来源 | 香侬科技本文整理了ICLR2020的相关论文&#xff0c;此次分享的是从Openreview中选取的部分论文&#xff0c;共50篇&#xff0c;其中大部分为NLP相关。文中涉及的相关论文推荐指数与推荐理由仅为个人观点&#xff0c;利益无关&#xff0c;亦不代表香侬科技立场。希望大家…

14个Xcode中常用的快捷键操作

在Xcode 6中有许多快捷键的设定可以使得你的编程工作更为高效&#xff0c;对于在代码文件中快速导航、定位Bug以及新增应用特性都是极有效的。 当然&#xff0c;你戳进这篇文章的目的也在于想要快速的对代码文件进行操作&#xff0c;或者是让Xcode的各面板更为适应你小本子的屏…

C++中标准模板库std::pair的实现

以下用C实现了标准模板库中的std::pair实现&#xff0c;参考了 cplusplus 和 vs2013中的utility文件。关于std::pair的介绍和用法可以参考&#xff1a; https://blog.csdn.net/fengbingchun/article/details/52205149 实现代码pair.hpp如下&#xff1a; #ifndef FBC_STL_PAIR_H…

【人在职场】能力与价值

原创作品&#xff0c;允许转载&#xff0c;转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://yunli.blog.51cto.com/831344/1547051 最近给团队&#xff08;指#UC浏览器电脑版#开发团队&#xff09;分享了我的《基层技术管理原则》。…

Windows与Linux之间互传文件的方法

以下方法均是以Windows为操作机&#xff1a;1. 通过WinSCP:WinSCP是一款开源的SFTP客户端&#xff0c;运行于Windows系统下&#xff0c;遵照GPL发布。WinSCP除了SFTP&#xff0c;还支持SSH、SCP(SecureCopy Protocol)。WinSCP的开发始于2000年4月&#xff0c;由布拉格经济大学所…

一文读懂简化的图卷积网络GCN(SGC)| ICML 2019

作者 | yyl424525来源 | CSDN博客文章目录1 相关介绍1.1 Simple Graph Convolution (SGC)提出的背景1.2 SGC效果2 Simple Graph Convolution 简化的图卷积2.1 符号定义2.2 图卷积网络GCNGCN vs MLPFeature propagation 特征传播Feature transformation and nonlinear transitio…

iOS UITableViewCell重用问题

TableView的重用机制&#xff0c;为了做到显示和数据分离&#xff0c;iOS tableView的实现并且不是为每个数据项创建一个tableCell。而是只创建屏幕可显示最大个数的cell&#xff0c;然后重复使用这些cell&#xff0c;对cell做单独的显示配置&#xff0c;来达到既不影响显示效果…

NLP常用工具

为什么80%的码农都做不了架构师&#xff1f;>>> NLP常用工具 各种工具包的有效利用可以使研究者事半功倍。 以下是NLP版版友们提供整理的NLP研究工具包。 同时欢迎大家提供更多更好用的工具包&#xff0c;造福国内的NLP研究。 *NLP Toolbox CLT http://compl…

Swift快速入门之getter 和 setter

属性可以用getter和setter方法的形式提供。 <code class"hljs lasso has-numbering" style"display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: Source Code Pro, monospace;font-size:u…

Linux下getopt函数的使用

getopt为解析命令行参数函数&#xff0c;它是Linux C库函数。使用此函数需要包含系统头文件unistd.h。 getopt函数声明如下&#xff1a; int getopt(int argc, char * const argv[], const char * optstring); 其中函数的argc和argv参数通常直接从main的参数直接传递而来。o…

20行Python代码说清“量子霸权”

作者 | 马超 来源 | 程序人生&#xff08;ID:coder_life&#xff09;近日谷歌的有关量子霸权&#xff08;Quantum Supremacy&#xff09;的论文登上了Nature杂志150年刊的封面位置&#xff0c;而再次罢占各大媒体的头条位置&#xff0c;其实这篇文章之前曾经短暂上过NASA的网站…

Android组件系列----BroadcastReceiver广播接收器

​【声明】 欢迎转载&#xff0c;但请保留文章原始出处→_→ 生命壹号&#xff1a;http://www.cnblogs.com/smyhvae/ 文章来源&#xff1a;http://www.cnblogs.com/smyhvae/p/3960623.html 【正文】 一、广播的功能和特征 广播的生命周期很短&#xff0c;经过调用对象-->…

Swift 代码调试-善用XCode工具(UI调试,五种断点,预览UIImage...)

原创Blog&#xff0c;转载请注明出处 http://blog.csdn.net/hello_hwc?viewmodelist 我的stackoverflow 工欲善其事&#xff0c;必先利其器&#xff0c;强烈建议新手同学好好研究下XCode这个工具。比如Build Settings&#xff0c;Build Info Rules&#xff0c;Build Parse…

Linux下getopt_long函数的使用

getopt_long为解析命令行参数函数&#xff0c;它是Linux C库函数。使用此函数需要包含系统头文件getopt.h。 getopt_long函数声明如下&#xff1a; int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);…

Expect自动化控制简单介绍

telnet&#xff0c;ftp&#xff0c;Passwd&#xff0c;fsck&#xff0c;rlogin&#xff0c;tip&#xff0c;ssh等等。该工具利用Unix伪终端包装其子进程&#xff0c;允许任意程序通过终端接入进行自动化控制&#xff1b;也可利用Tk工具&#xff0c;将交互程序包装在X11的图形用…