app多语言设置 swift3
2017-03-02 23:13:00 weixin_34342905 阅读数 22
// 系统为我们创建了下面这个类
// UIApplication 实时帮我们监听应用程序状态的一个类

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    // 声明成员变量 (相当于OC中的属性 @property)
    var window: UIWindow?
    
    // 当应用程序已经加载到内存是调用该方法
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        print("程序被加载到内存")
        return true
    }

    // 当应用程序取消激活状态时调用该方法
    func applicationWillResignActive(_ application: UIApplication) {
        print("取消激活")
    }

    // 当应用程序已经进入到后台时调用该方法
    func applicationDidEnterBackground(_ application: UIApplication) {
        
        print("已经进入后台")
    
    }

    // 当应用程序进入前台时调用该方法
    func applicationWillEnterForeground(_ application: UIApplication) {
        print("将要进入前台")
    }

    // 当应用程序已经被激活时调用该方法
    func applicationDidBecomeActive(_ application: UIApplication) {
        print("程序被激活")
    }

    // 当应用程序结束时调用该方法
    func applicationWillTerminate(_ application: UIApplication) {
        print("程序结束")
    }


}
2015-08-20 17:02:00 weixin_34064653 阅读数 20

** 转载请注明出处:http://www.jianshu.com/p/024dd2d6e6e6#**

已更新至 Xcode8.2、Swift3

在第一次打开App或者App更新后通常用引导页来展示产品特性

我们用NSUserDefaults类来判断程序是不是第一次启动或是否更新,在 AppDelegate.swift中加入以下代码:

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // 得到当前应用的版本号
    let infoDictionary = Bundle.main.infoDictionary
    let currentAppVersion = infoDictionary!["CFBundleShortVersionString"] as! String
        
    // 取出之前保存的版本号
    let userDefaults = UserDefaults.standard
    let appVersion = userDefaults.string(forKey: "appVersion")
        
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
        
    // 如果 appVersion 为 nil 说明是第一次启动;如果 appVersion 不等于 currentAppVersion 说明是更新了
    if appVersion == nil || appVersion != currentAppVersion {
        // 保存最新的版本号
        userDefaults.setValue(currentAppVersion, forKey: "appVersion")
            
        let guideViewController = storyboard.instantiateViewController(withIdentifier: "GuideViewController") as! GuideViewController
        self.window?.rootViewController = guideViewController
    }
        
    return true
}

GuideViewController中,我们用UIScrollView来装载我们的引导页:

class GuideViewController: UIViewController {
    
    @IBOutlet weak var pageControl: UIPageControl!
    @IBOutlet weak var startButton: UIButton!
    
    fileprivate var scrollView: UIScrollView!
    
    fileprivate let numOfPages = 3

    override func viewDidLoad() {
        super.viewDidLoad()

        let frame = self.view.bounds
        
        scrollView = UIScrollView(frame: frame)
        scrollView.isPagingEnabled = true
        scrollView.showsHorizontalScrollIndicator = false
        scrollView.showsVerticalScrollIndicator = false
        scrollView.scrollsToTop = false
        scrollView.bounces = false
        scrollView.contentOffset = CGPoint.zero
        // 将 scrollView 的 contentSize 设为屏幕宽度的3倍(根据实际情况改变)
        scrollView.contentSize = CGSize(width: frame.size.width * CGFloat(numOfPages), height: frame.size.height)
        
        scrollView.delegate = self
        
        for index  in 0..<numOfPages {
            let imageView = UIImageView(image: UIImage(named: "GuideImage\(index + 1)"))
            imageView.frame = CGRect(x: frame.size.width * CGFloat(index), y: 0, width: frame.size.width, height: frame.size.height)
            scrollView.addSubview(imageView)
        }
        
        self.view.insertSubview(scrollView, at: 0)
        
        // 给开始按钮设置圆角
        startButton.layer.cornerRadius = 15.0
        // 隐藏开始按钮
        startButton.alpha = 0.0
    }
    
    // 隐藏状态栏
    override var prefersStatusBarHidden : Bool {
        return true
    }
}

最后我们让GuideViewController遵循UIScrollViewDelegate协议,在这里判断是否滑动到最后一张以显示进入按钮:

// MARK: - UIScrollViewDelegate
extension GuideViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let offset = scrollView.contentOffset
        // 随着滑动改变pageControl的状态
        pageControl.currentPage = Int(offset.x / view.bounds.width)
        
        // 因为currentPage是从0开始,所以numOfPages减1
        if pageControl.currentPage == numOfPages - 1 {
            UIView.animate(withDuration: 0.5, animations: {
                self.startButton.alpha = 1.0
            }) 
        } else {
            UIView.animate(withDuration: 0.2, animations: {
                self.startButton.alpha = 0.0
            }) 
        }
    }
}

在上面的代码中,为了显得自然我们给进入按钮加入了一点动画 :]

最终效果如下:


179888-648bc09efcd64289.gif
GuideScreenshot.gif

Github地址:https://github.com/GuiminChu/JianshuExample

2015-12-06 00:27:00 weixin_34367257 阅读数 7

Chapter 4

Hello World App的解释

做一个app简单吗?我希望你享受第一章的阅读并且已经制作了你的第一个iPhone app.

在我们继续探索iOS SDK之前,我们暂停一下来近距离的看下这个Hello World app.这对你理解Swift语言的基础和app的内部工作情况来说很有帮助.

迄今为止,你跟着一步一步的来制作Hello World app.像你通过阅读这一章,你可能会在脑海里有一些疑问:

  • storyboard里的ViewController是这怎么和ViewController类里面的ViewController.swift文件联系上的呢?

  • showMessage()方法里面的代码块的意思是什么?它是怎样告诉iOS来显示一个Hello World信息的?

  • @IBAcation 关键字的意思是什么?

  • "Hello World"按钮背后是什么?按钮是怎样察觉轻触然后触发showMessage()方法的?

  • 运行按钮在Xcode是怎样工作的?你说的"编译一个app"是什么意思?

之前我想让你专注于探索Xcode环境所以我没有解释任何以上的问题.然而,对每个开发者来说,理解代码背后的细节和领会iOS编程的基本概念是至关重要的.技术概念可能会有点难理解,特别是,如果你之前没有任何编程经验.不要担心这刚刚开始.在之后的章节,随着你继续学习和写更多的代码,你将对iOS编程有一个更好的理解.尽你最大的努力去学习,越多越好.

我们来看一个真实生活的案例

想象一个电视遥控器.它可以在远距离很方便的无线遥控电视的音量.切换电视频道,你仅仅需要按频道数字.增加电视音量,你只要按音量+按钮.

我来告诉你.你知道当你按下音量按钮或者频道按钮发生了什么吗?可能不知道.我相信我们大多数人不知道遥控器是怎样无线遥控电视机的.你可能会想到遥控器发送一个确定的信息给电视机然后触发音量增加或者切换频道.

在这里例子里,跟你互动的按钮通常被描述成接口,隐藏在按钮之后的内部细节归类为实施.接口通过一条信息与实施联系起来.

这个概念同样能在iOS编程世界里实现.storyboard里的界面是接口,代码则是安装启用.用户界面元素(如按钮)通过信息来与代码沟通.

具体的说,如果你回到Hello World项目,你在视图里添加的按钮就是界面.Viewcontroller类里面的showMessage()方法则是实施(implementation).当有人按下按钮,它发送一个showMessage的信息给ViewController来唤醒showMessage的方法.

我们刚才演示的是一个面向对象工程(OOP)中非常重要的概念,叫做封装.showMessage方法的实施隐藏在外部世界(如界面).Hello World按钮不知道showMessage()方法怎样工作.它所知道的是它需要发送信息.showMessage()方法通过在屏幕上演示一条"Hello World"信息处理其它的.

Quick note:和OC一样,Swift是一个面向对象工程(OOP)语言.大多数app中的代码用同样的方法处理一类对象.在这里我教你OOP概念不是想要把你吓跑.继续阅读.你会学习更多关于OOP的内容.

触摸的背后

现在你应该理解UI里的按钮是怎样和代码联系的,我们来看看当一个用户按下"Hello World"按钮实际上发生了什么?"Hello World"按钮是怎样调用执行showMessage方法的?

你记得你是怎么在界面编辑器中建立Hello World按钮和showMessage方法之间的联系的吗?再次打开Main.storyboard,选择"Hello World"按钮.点击多功能区的Connection inspector标志.在发送事件的部分,你应该可以找到一条可用的事件及其对应的方法调用.像你在下图看见的一样,Touch Up Inside事件联系着showMessage()方法.

在iOS,apps是基于事件驱动的编程.不管是系统对象还是UI对象,都听从于特定的事件来确定app的流程.一个UI对象(如按钮),它可能听从于一个特定的触摸事件.当触发事件时,这个对象唤醒预设的方法来和事件合作.

在Hello World app里,当用户抬起手指放在按钮上的时候,"Touch Up Inside"事件被触发.因此,它唤醒showMessage()方法来演示"Hello World"信息.由于我们想要避免意外或者错误的触摸,所以用"Touch Up Inside"事件代替"Touch Down".

showMessage方法里面

你现在应该对iOS编程有了更好的理解.但是showMessage方法里的代码块是什么呢?

先说重要的,方法是什么?像之前提到的,一个app里的大部分代码用一些方法处理一些类型的对象.每一个对象提供确定的功能和执行特定的任务(如在屏幕上演示一条信息).这些功能当用代码表达时,我们称之为方法.现在,让我们近距离的观看showMessage()方法.

Quick note:我知道理解这些代码对你来说有点难.如果你是编程纯小白,可能需要一段时间来理解OOP.别放弃,因为如果我们继续,你将对对象,类和方法获得一个更好的理解.你也可以看看附件来学习更多的Swift知识.或者参照Playgrounds章节里的小练习.

在Swift里,为了在一个类里声明一个方法,我们用func关键字.func关键字和方法是一个意思.这个名字可以识别方法同时让方法更容易被你代码里其他地方的唤醒.方法可以输入参数.参数用圆括号界定.在我们的例子里,方法不需要任何参数.在这种情况下,我们之间简单的写下一对空括号.在方法声明里有一个关键字我们还没探讨过叫做@IBAction.这个关键字允许你在界面编辑器中联系你的源代码到用户界面对象.当它插入方法声明中的时候,意味着这个方法可以暴露给用户编辑器.这就是为什么当你连接Hello World按钮和代码时会有个showMessage事件出现在pop-over里,如果你不知道我在说什么你可以再看一次下面的图

OK,方法的声明说的够多了.我们来说说花括号里封闭的代码块.

代码块是实际执行任务的方法.但是,在iOS里开发app的时候,我们不需要总是从头编写所有的功能.例如,你不需要学习如何在屏幕上画出警告框.你可以利用iOS SDK框架提供的类来担当重任.iOS SDK 带来的各种frameworks和kist会让你更轻松.例如,UIKit框架提供类来构建和管理你app的用户界面.

这里我们依靠UIAlertController来创建Hello World消息.一个UIAlertController对象显示一个警告信息给用户.第一行代码创建一个UIAlertController对象.从一个类构建一个对象的语法和调用一个方法很像.你指定类名,紧随其后的是一组属性的初始值.这里我们指定标题,消息和警报的风格:

let alertController = UIAlertController(title: "Hello World", message: "Hello World", prefeStyle: UIAlertControllerStyle.Alert)

创建UIAlertController类(如alertController)之后,我们调用addAction方法来增加一个动作给警报,它会显示"OK"按钮.在Swift工程里,你可以用.来呼出一个方法.

alertController.addAction(UIAlertAction(title: "ok", style: UIAlertActionStyle.Default, handler: nil))

你可能想知道你怎么才能找到用法和一个类可用的方法.在Xcode里,你可以按住option键,点击类的名字(如UIAlertController).pop-over会出现来显示类的描述.你可以更多的信息通过检查类的参考文献.

UIAlertController对象配置好以后,最后一条代码是在屏幕上显示的警告信息.

self.presentViewController(alertController, animated: true, completion: nil)

在Swift,你可以用self属性来引用当前实例(或对象).

在大多数的情况下,self关键词是可选的.你可以简单的写下面的代码:

presentViewController(alertController, animated: true, completion: nil)

界面和代码的关系

Xcode是怎样知道界面编辑器里的ViewController与ViewController.swift里定义的ViewController类联系起来的呢?

整个事情看起来不重要但是事实上并不是如此.你还记得我们创建Xcode样板工程时选择的模板吗?我们选的是"Single View Application"模板.当用这个工程模板时,它会在界面编辑器里自动创建一个默认的view controller然后生成ViewController.swift.综上所述,view controller是自动和定义在swift文件里的ViewController类相连的.

我们来到storyboard,选择View Controller.在多功能区域里,选择Identity inspector图标,你会发现ViewController被设置成标准类.这就是界面编辑器里的对象是怎样与Swift代码类关联的.

屏幕背后的运行按钮

我想跟你们讨论的最后一件事是运行按钮.当你点击运行按钮时,Xcode自动登录模拟器然后运行你的app.屏幕后面发生了什么?作为一个开发者,你应该看看所有的部分.

整个进程可以被分解成三段:编译,打包和运行.

  • 编译 --你很可能认为iOS理解Swift代码.事实上,iOS仅仅只能阅读机器码.Swift代码是为开发者读写准备的.为了让iOS理解app的源代码,它不得不进行一个翻译进程来把Swift代码翻译成机器代码.这个过程被称为"编译".Xcode已经附带了一个内置编译器来编译源代码

  • 打包 --除了源代码,一个app通常包含源文件比如图像,文本文件,声音文件等等.所有这些资源都被打包在一起来生成最终的app.我们把这两个过程叫做"构建"过程.

  • 运行 --实际上的登录模拟器和读取你的app.

摘要

你现在应该对Hello World app工作有一个基本的认识.作为一个没有任何编程经验的初学者,要弄清楚我们之前讨论的所有编程概念并不容易.不要担心.当你写下更多代码然后在下一章开发一个真正的app滞后,你会对Swift和iOS编程有一个更清晰的认识.


转载于:https://my.oschina.net/zt223/blog/539782

2017-01-17 21:19:39 Enter_ 阅读数 2099

在显示进度条的时候,有时候会发现用自带的progressView可自定义的属性比较少,并不能满足某些需求,继承UIView重新实现一个也挺方便的,自定义progress view 代码如下:

import Foundation
import UIKit

class DOVProgressView: UIView {


    private let textLabel = UILabel()


    private let bar = UIView()

    public var progress: Float = 0{
        didSet{
            percent = Int(progress * 100)
        }
    }

    var percent: Int = 0 {
        didSet {
            if percent > 100 {
                percent = 100
            }else if percent < 0 {
                percent = 0
            }
            textLabel.text =  "\(percent)%"
            setNeedsLayout()
        }
    }

    //文本颜色
    var color: UIColor = UIColor.black {
        didSet {
            textLabel.textColor = color
        }
    }

    //进度条颜色
    var barColor: UIColor = UIColor.orange {
        didSet {
            bar.backgroundColor = barColor
        }
    }

    //进度条背景颜色
    var barBgColor: UIColor = UIColor.white {
        didSet {
            layer.backgroundColor = barBgColor.cgColor
        }
    }


    override init(frame: CGRect) {
        super.init(frame: frame)

        initialSetup()
    }


    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        initialSetup()
    }

    private func initialSetup(){
        bar.backgroundColor = self.barColor
        addSubview(bar)

        self.layer.cornerRadius = CGFloat(12)
        self.layer.masksToBounds = true
        self.bar.layer.cornerRadius = CGFloat(12)
        self.bar.layer.masksToBounds = true

        textLabel.textAlignment = .center
        textLabel.numberOfLines = 0
        textLabel.textColor = self.color
        textLabel.text = "\(self.percent)%"
        addSubview(textLabel)
    }


    override func layoutSubviews() {
        super.layoutSubviews()

        layer.backgroundColor = self.barBgColor.cgColor

        var barFrame = bounds
        barFrame.size.width *= (CGFloat(self.percent) / 100)
        bar.frame = barFrame

        textLabel.frame = bounds
    }
}

自定义进度条后,想让进度条显示在一个半透明的背景上,这样的操作还是经常遇到的,可以直接在屏幕上加一个Window,然后把自定义的进度条显示在上面,代码如下:

import Foundation
import UIKit

class DOVUserInteractiveManager: NSObject {

    private var _boardWindow : UIWindow?

    static let shared : CXEUserInteractiveManager = {
        let instance = CXEUserInteractiveManager.init()
        return instance
    }()

    //    MARK:load界面
    var boardWindow : UIWindow {
        if(self._boardWindow == nil) {

            let window : UIWindow = UIWindow(frame: UIScreen.main.bounds)
            window.windowLevel = UIWindowLevelStatusBar
            window.backgroundColor = UIColor.gray.withAlphaComponent(0.7)
            window.isUserInteractionEnabled = true
            window.makeKeyAndVisible()


            self._boardWindow = window
        }
        return self._boardWindow!
    }

    public func diss() {
        self.boardWindow.isHidden = true
        self.boardWindow.removeFromSuperview()
    }

    public func show(_ view : UIView) {
        self.boardWindow.addSubview(view)
        self.boardWindow.isHidden = false
    }

}

使用方法如下:

import UIKit

class ViewController: UIViewController {

    var timer:Timer?
    var progress:Float = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        let button = UIButton(type: .system)
        button.setTitle("点我点我点我", for: .normal)
        button.frame = CGRect(x:0, y:0, width:Int(UIScreen.main.bounds.width.native * 0.8), height:30)
        button.center = CGPoint(x: UIScreen.main.bounds.midX, y: UIScreen.main.bounds.midY - 50)
        button.addTarget(self, action: #selector(self.onClike), for: .touchUpInside)

        self.view.addSubview(button)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func onClike(){
        let progressView = CXEProgressView(frame: CGRect(x:0, y:0, width:Int(UIScreen.main.bounds.width.native * 0.8), height:22))
        progressView.center = CGPoint(x: UIScreen.main.bounds.midX, y: UIScreen.main.bounds.midY)
        DOVUserInteractiveManager.shared.show(progressView)

        let cancelProgressButton = UIButton(type: .system)
        cancelProgressButton.frame = CGRect(x: 0, y: 0, width: Int(UIScreen.main.bounds.width.native * 0.8), height: 60)
        cancelProgressButton.center = CGPoint(x: UIScreen.main.bounds.midX, y: UIScreen.main.bounds.midY + 80)
        let attributes:[String:Any] = [NSFontAttributeName: UIFont.systemFont(ofSize: 15)]
        cancelProgressButton.setAttributedTitle(NSAttributedString(string:"你再点我试试", attributes: attributes), for: .normal)
        cancelProgressButton.tintColor = UIColor.white
        cancelProgressButton.addTarget(self, action: #selector(self.onCancleProgress), for: .touchUpInside)
        DOVUserInteractiveManager.shared.show(cancelProgressButton)

        timer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true){_ in 
            progressView.progress = self.progress
            self.progress += 0.1
        }
    }

    func onCancleProgress(){
        CXEUserInteractiveManager.shared.diss()
        self.timer?.invalidate()
    }
}


Contact GitHub API Training Shop Blog About

Demo下载:https://github.com/Willib/CustomProgress

效果如下:
运行截图

2015-03-10 15:36:44 weixin_33816821 阅读数 8

Swift90Days - 用 Swift 开发 Mac App 1 / 3

今天抽点时间找了篇 Raywenderlich 上的教程入门了一下 Mac App 的开发。

教程的例子是实现一个简单的 TableView ,不过在 Mac 里它叫做 NSTableView

用法也和 UITableView 相似,通过 delegatedatasource 来加载列表:

import Cocoa

class MasterViewController: NSViewController, NSTableViewDataSource, NSTableViewDelegate {

    var bugs: [ScaryBugDoc]!

    override func viewDidLoad() {
        super.viewDidLoad()

        // init bugs
        var doc1 = ScaryBugDoc(title: "Potato Bug", rating: 4, thumbImage:NSImage(named:"potatoBugThumb")!, fullImage: NSImage(named:"potatoBug")!)
        var doc2 = ScaryBugDoc(title: "House Centipede", rating: 4, thumbImage:NSImage(named:"centipedeThumb")!, fullImage: NSImage(named:"centipede")!)
        var doc3 = ScaryBugDoc(title: "Wolf Spider", rating: 4, thumbImage:NSImage(named:"wolfSpiderThumb")!, fullImage: NSImage(named:"wolfSpider")!)
        var doc4 = ScaryBugDoc(title: "Lady Bug", rating: 4, thumbImage:NSImage(named:"ladybugThumb")!, fullImage: NSImage(named:"ladybug")!)
        bugs = [doc1,doc2,doc3,doc4]
    }



    // MARK: NSTableViewDataSource
    func tableView(tableView: NSTableView!, viewForTableColumn tableColumn: NSTableColumn!, row: Int) -> NSView! {
        var cellView = tableView.makeViewWithIdentifier(tableColumn.identifier, owner: self) as NSTableCellView
        if cellView.identifier == "BugColumn" {
            var doc = bugs[row]
            cellView.imageView?.image = doc.thumbImage
            cellView.textField?.stringValue = doc.data.title
        }
        return cellView;
    }

    func numberOfRowsInTableView(tableView: NSTableView) -> Int {
        return bugs.count
    }

}

好吧就这么点了,感兴趣的同学可以看下文末的教程链接。


原文链接:

没有更多推荐了,返回首页