Для работы с форматом JSON во фреймворке Foundation имеется класс NSJSONSerialization. Он позволяет выполнять две основные вещи: переводить объекты в JSON-данные — сериализовать, и наоборот, из JSON-данных получать объекты — десериализовать.
/*
articles.json format:
[
{
"article": {
"title": "Холст для рисования",
"url": "http://valery.bashkatov.org/paper/canvasview",
"date": "2016-01-22"
}
},
{
"article": {
"title": "Вызов метода по таймеру",
"url": "http://valery.bashkatov.org/paper/method-call-by-timer",
"date": "2016-01-17"
}
}
]
*/
import Foundation
typealias Article = [String: [String: String]]!
let url = NSURL(string: "http://valery.bashkatov.org/files/json/articles.json")!
var data = NSData(contentsOfURL: url)!
var articles: [Article]!
do {
// JSON data deserialization into the object
articles = try NSJSONSerialization.JSONObjectWithData(data,
options: NSJSONReadingOptions()) as! [Article]
} catch {
print(error)
}
for article in articles {
print("article")
}
if NSJSONSerialization.isValidJSONObject(articles) {
do {
// Object serialization into the JSON data
data = try NSJSONSerialization.dataWithJSONObject(articles,
options: NSJSONWritingOptions.PrettyPrinted)
} catch {
print(error)
}
}
print(String(data: data, encoding: NSUTF8StringEncoding)!)
Рисование фигур внутри UIView производится через задание в подклассе логики методу drawRect. Каждый раз создавать нового наследника непрактично, кроме того, такой способ не отличается гибкостью в плане управления процессом рисования.
Полезно иметь класс-холст. Для себя я разработал CanvasView. С ним рисование сводится к добавлению нужных путей в массив. CanvasPath — банальный наследник UIBezierPath с цветами обводки и заливки.
import UIKit
/**
The `CanvasPath` class extends UIBezierPath by adding stroke and fill colors.
Used in `CanvasView` class.
*/
class CanvasPath: UIBezierPath {
// MARK: - Properties
/**
The stroke color.
*/
var strokeColor: UIColor?
/**
The fill color.
*/
var fillColor: UIColor?
}
/**
The `CanvasView` class makes it easy to draw the shapes inside.
*/
class CanvasView: UIView {
// MARK: - Properties
/**
The paths that are be drawn.
*/
var paths = [CanvasPath]() {
didSet {
// Redraw paths
setNeedsDisplay()
}
}
// MARK: - Initialization
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
// Set false for default transparent background color.
opaque = false
}
// MARK: - Drawing
override func drawRect(rect: CGRect) {
for path in paths {
if path.strokeColor != nil {
path.strokeColor!.setStroke()
path.stroke()
}
if path.fillColor != nil {
path.fillColor!.setFill()
path.fill()
}
}
}
}
Пример использования.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let canvas = CanvasView(frame: CGRect(x: 0, y: 0, width: 400, height: 300))
let borders = CanvasPath()
borders.strokeColor = UIColor(white: 0.9, alpha: 1)
borders.moveToPoint(CGPoint(x: 20, y: 50))
borders.addLineToPoint(CGPoint(x: 350, y: 50))
borders.addLineToPoint(CGPoint(x: 350, y: 275))
borders.addLineToPoint(CGPoint(x: 20, y: 275))
borders.addLineToPoint(CGPoint(x: 20, y: 50))
let white = CanvasPath(rect: CGRect(x: 20, y: 50, width: 330, height: 75))
white.fillColor = UIColor.whiteColor()
let blue = CanvasPath(rect: CGRect(x: 20, y: 125, width: 330, height: 75))
blue.fillColor = UIColor(red: 0, green: 0.224, blue: 0.651, alpha: 1)
let red = CanvasPath(rect: CGRect(x: 20, y: 200, width: 330, height: 75))
red.fillColor = UIColor(red: 0.835, green: 0.169, blue: 0.118, alpha: 1)
canvas.paths += [borders, white, blue, red]
view.addSubview(canvas)
}
}
Скачать CanvasView.zip
Если код нужно выполнить через определенный интервал времени, поможет класс NSTimer и его статический метод scheduledTimerWithTimeInterval.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
/* Parameters:
1) interval — number of seconds between firings
2) target — object-owner of the called method
3) selector — name of the called method
4) userInfo — additional user info object (may be nil)
5) repeats — timer is fired once (false) or until invalidated (true)
*/
NSTimer.scheduledTimerWithTimeInterval(5,
target: self,
selector: "changeBackgroundColor:",
userInfo: nil,
repeats: true)
}
func changeBackgroundColor(timer: NSTimer) {
// Generate random color
let red = CGFloat(arc4random_uniform(3)) / 2
let green = CGFloat(arc4random_uniform(3)) / 2
let blue = CGFloat(arc4random_uniform(3)) / 2
let alpha = CGFloat(1)
let color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
// Animate background color changes
UIView.animateWithDuration(1, animations: {
self.view.backgroundColor = color
})
print("New background color: \(color)")
// If the new color is white, then stop the timer
if color == UIColor(red: 1, green: 1, blue: 1, alpha: 1) {
timer.invalidate()
print("The timer is stopped")
}
}
}
У строк есть ряд дополнительных методов для отрисовки и вычисления занимаемой на экране области. Показывать текст все же лучше через компоненты графического интерфейса, а вот определение размера может быть полезным.
Метод sizeWithAttributes принимает на вход словарь атрибутов и возвращает прямоугольную область, необходимую для отображения строки с такими параметрами. Допустимые атрибуты: шрифт, толщина обводки, межбуквенный интервал, тень и другие декорации; полный список — в документации.
import UIKit
class ViewController: UIViewController {
var stringLabel = UILabel()
var stringSize = UIView()
let stringAttributes: [String: AnyObject] =
[
NSFontAttributeName: UIFont.systemFontOfSize(25),
NSStrokeWidthAttributeName: 5
]
override func viewDidLoad() {
super.viewDidLoad()
stringLabel.frame = CGRect(x: 0, y: 100, width: 300, height: 50)
stringLabel.backgroundColor = UIColor.yellowColor()
stringLabel.attributedText = NSAttributedString(string: "Luke, I'm not your father",
attributes: stringAttributes)
stringSize.frame = CGRect(x: 0, y: 160, width: 0, height: 0)
stringSize.backgroundColor = UIColor(white: 0.9, alpha: 1)
view.addSubview(stringLabel)
view.addSubview(stringSize)
stringSize.frame.size = stringLabel.text!.sizeWithAttributes(stringAttributes)
}
}
Статусная строка — это область в верхней части экрана, на которой отображается системная информация.
Есть два способа ее скрыть. Первый — глобально для приложения, задав в Info.plist свойства View controller-based status bar appearance = NO и Status bar is initially hidden = YES.
Второй — для отдельного контроллера, определив ему метод prefersStatusBarHidden, возвращающий true.
import UIKit
class ViewController: UIViewController {
override func prefersStatusBarHidden() -> Bool {
return true
}
}
На экране результат будет одинаковым.