2015-12-23 1 views
13

Прежде чем писать этот вопрос, у меняКак сделать трансляции на CALayer?

Однако мне все еще трудно понять, как делать базовые преобразования на слой. Найти объяснения и простые примеры для перевода, поворота и масштабирования было сложно.

Сегодня я наконец решил сесть, сделать тестовый проект и выяснить их. Мой ответ ниже.

Примечания:

  • я делаю только Swift, но если кто-то хочет, чтобы добавить код Objective-C, быть моим гостем.
  • На данный момент меня интересует только двумерные преобразования.

ответ

51

Основа

Есть целый ряд различных трансформирует вы можете сделать на слое, но основные из них являются

  • перевода (перемещения)
  • шкала
  • вращаются

enter image description here

Чтобы сделать преобразования на CALayer, вы устанавливаете свойство transform слоя на тип CATransform3D. Например, чтобы перевести слой, вы могли бы сделать что-то вроде этого:

myLayer.transform = CATransform3DMakeTranslation(20, 30, 0) 

Слово Make используется в названии для создания начального преобразования: CATransform3D Сделать перевод. Последующие преобразования, которые применяются, опускают Make. Смотрите, например, этот поворот, за которым следует перевод:

let rotation = CATransform3DMakeRotation(CGFloat.pi * 30.0/180.0, 20, 20, 0) 
myLayer.transform = CATransform3DTranslate(rotation, 20, 30, 0) 

Теперь у нас есть основа того, как сделать преобразование, давайте рассмотрим некоторые примеры того, как сделать каждый из них. Во-первых, я покажу, как я создаю проект, если вы хотите поиграть с ним.

Настройка

В следующих примерах я воздвигну Single View Application и добавил UIView с голубым фоном к раскадровке.Я подключил вид на контроллер представления со следующим кодом:

import UIKit 

class ViewController: UIViewController { 

    var myLayer = CATextLayer() 
    @IBOutlet weak var myView: UIView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // setup the sublayer 
     addSubLayer() 

     // do the transform 
     transformExample() 
    } 

    func addSubLayer() { 
     myLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 40) 
     myLayer.backgroundColor = UIColor.blue.cgColor 
     myLayer.string = "Hello" 
     myView.layer.addSublayer(myLayer) 
    } 

    //******** Replace this function with the examples below ******** 

    func transformExample() { 

     // add transform code here ... 


    } 

} 

There are many different kinds of CALayer, но я решил использовать CATextLayer так, что преобразования будут более ясным визуально.

Перевести

Преобразование перевода перемещает слой. Базовый синтаксис

CATransform3DMakeTranslation(tx: CGFloat, ty: CGFloat, tz: CGFloat) 

, где tx это изменение координаты х, ty является изменение у, и tz является изменение г.

Пример

enter image description here

В прошивкой начало системы координат находится в верхнем левом углу, так что, если мы хотим, чтобы переместить слой 90 точек вправо и 50 пунктов вниз, мы бы выполните следующие действия:

myLayer.transform = CATransform3DMakeTranslation(90, 50, 0) 

Примечания

  • Помните, что вы можете вставить это в метод transformExample() в код проекта выше.
  • Поскольку мы сейчас будем иметь дело с двумя измерениями, tz настроен на 0.
  • Красная линия на изображении выше идет от центра первоначального местоположения до центра нового места. Это потому, что преобразования выполняются по отношению к опорной точке и точка привязки по умолчанию находится в центре слоя.

Масштаб

Шкала преобразования вытягивание или хлюпает слой. Базовый синтаксис

CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat) 

, где sx, sy и sz являются номерами, по которым можно масштабировать (многократно) х, у, г координаты соответственно.

Пример

enter image description here

Если мы хотим половину ширины и тройной высоты, мы делаем следующие

myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0) 

Примечания

  • Так как мы только работая в двух измерениях, мы просто умножаем координаты z на 1.0, чтобы они не были затронуты.
  • Красная точка на изображении выше представляет собой точку привязки. Обратите внимание на то, как масштабирование делается по отношению к точке привязки. То есть, все, либо растянуто в стороне или от точки привязки.

Поворот

Вращение преобразования поворачивает слой вокруг опорной точки (центр слоя по умолчанию). Базовый синтаксис

CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat) 

angle, где находится угол в радианах, что слой должен быть повернут и x, y и z являются осями, о которых вращаться. Установка оси на 0 отменяет поворот вокруг этой конкретной оси.

Пример

enter image description here

Если мы хотим, чтобы повернуть слой, по часовой стрелке на 30 градусов, мы делаем следующее:

let degrees = 30.0 
let radians = CGFloat(degrees * Double.pi/180) 
myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0) 

Примечания

  • Поскольку мы работая в двух измерениях, мы хотим только плоскость xy должна вращаться вокруг оси z. Таким образом, мы установили x и y в 0.0 и установили z в 1.0.
  • Это повернуло слой по часовой стрелке. Мы могли бы повернуться против часовой стрелки, установив z в -1.0.
  • Красная точка показывает, где находится опорная точка. Вращение осуществляется вокруг точки привязки.

Multiple трансформирует

Для того, чтобы объединить несколько преобразований, мы могли бы использовать concatination как этот

CATransform3DConcat(a: CATransform3D, b: CATransform3D) 

Однако, мы просто делаем одно за другим. Первое преобразование будет использовать имя Make. Следующие преобразования не будут использовать Make, но они будут принимать предыдущее преобразование в качестве параметра.

Пример

enter image description here

На этот раз мы соединим все три предыдущих преобразований.

let degrees = 30.0 
let radians = CGFloat(degrees * Double.pi/180) 

// translate 
var transform = CATransform3DMakeTranslation(90, 50, 0) 

// rotate 
transform = CATransform3DRotate(transform, radians, 0.0, 0.0, 1.0) 

// scale 
transform = CATransform3DScale(transform, 0.5, 3.0, 1.0) 

// apply the transforms 
myLayer.transform = transform 

Примечания

  • Порядок, что преобразования выполняются в вопросах.
  • Все было сделано по отношению к опорной точке (красная точка).

Примечание о точке привязки и положение

Мы сделали все наши преобразования выше, не меняя точку привязки.Иногда это необходимо изменить, хотя, например, если вы хотите повернуть вокруг какой-то другой точки, кроме центра. Однако это может быть немного сложно.

Опорная точка и положение находятся в одном и том же месте. Якорная точка выражается как единица системы координат слоя (по умолчанию 0.5, 0.5), и позиция выражается в системе координат суперслоя. Они могут быть установлены как этот

myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0) 
myLayer.position = CGPoint(x: 50, y: 50) 

Если вы только установить точку привязки, не меняя положения, то изменения кадров, так что положение будет в нужном месте. Или, точнее, рама пересчитываются на основе новой опорной точки и старой позиции. Это обычно дает неожиданные результаты. Следующие две статьи прекрасно обсуждают это.

Смотрите также