Как сохранить CATransform3D применяется на UIView - PullRequest
1 голос
/ 16 апреля 2019

У меня есть представление (Uiview), которое применило к нему CATransform3D, Я хочу создать такой же вид, как при повторном открытии приложения

Итак, я делаю: сохранить преобразование, чтобы позже использовать его в открытом приложении

   let radian_vertical =  element.layer.value(forKeyPath: "transform.rotation.y") as? NSNumber ?? 0
    let degree_vertical = (radian_vertical.floatValue) * 180 / (Float)(Double.pi)

    let radian_horizontal =  element.layer.value(forKeyPath: "transform.rotation.x") as? NSNumber ?? 0

   let degree_hori = (radian_horizontal.floatValue) * 180 / (Float)(Double.pi)

Но это не правильно, когда я применяю это позже

//saved_degree_vertical and saved_degree_hori. is saved from degree_vertical and degree_hori

 let radians_verti =  saved_degree_vertical * (CGFloat)(Double.pi)  / 180
 let radians_hori =  saved_degree_hori * (CGFloat)(Double.pi)  / 180
 let rotateVertical = CATransform3DRotate(newViewContent.layer.transform, CGFloat(radians_verti), 0, 1, 0)

 let rotateHorizontal = CATransform3DRotate(newViewContent.layer.transform, CGFloat(radians_hori), 1, 0, 0)

 newViewContent.layer.transform=  rotateHorizontal
 newViewContent.layer.transform =  rotateVertical
//save degree

1 Ответ

0 голосов
/ 16 апреля 2019

Вместо нескольких поворотов вы должны сохранить целую матрицу. A CATransform3D состоит из 16 значений, так как это матрица 4x4. Свойства называются m12, m13, ..., m43, m44. Он также имеет конструктор, который принимает все эти свойства.

Вы даже можете сериализовать все 16 значений в одну строку, а затем десериализовать ее, чтобы упростить ее. Смотрите что-то вроде следующего:

/// A method to save the current view matrix
func saveCurrentMatrix() {
    UserDefaults.standard.set(serializeViewMatrix(view: viewContent), forKey: "my_saved_matrix")
}

/// A method to apply the saved matrix to current view
func loadCurrentMatrix() {
    do {
        try applyViewMatrixFromSerializedString(view: viewContent, string: UserDefaults.standard.string(forKey: "my_saved_matrix"))
    } catch {
        if let description = (error as NSError).userInfo["dev_info"] as? String {
            print("Error occured applying saved matrix: \(description)")
        }
    }
}

/// Serializes a view.layer.transform matrix into string
///
/// - Parameter view: A view to save matrix from
/// - Returns: A string representation of the matrix. In format 1;0;0;0;0;1;0;0;0 ...
func serializeViewMatrix(view: UIView) -> String {
    let matrix: CATransform3D = view.layer.transform
    let values: [CGFloat] = [
        matrix.m11, matrix.m12, matrix.m13, matrix.m14,
        matrix.m21, matrix.m22, matrix.m23, matrix.m24,
        matrix.m31, matrix.m32, matrix.m33, matrix.m34,
        matrix.m41, matrix.m42, matrix.m43, matrix.m44
    ]
    return values.map { String(Double($0)) }.joined(separator: ";")
}

/// Creates a matrix from string produced by serializeViewMatrix and applies it to given view
///
/// - Parameters:
///   - view: A view to apply matrix to
///   - string: A string representing the matrix
/// - Throws: Will throw on incorrect data
func applyViewMatrixFromSerializedString(view: UIView, string: String?) throws {
    guard let string = string else { return } // Simply return if there is no string

    // Genereate 16 string componets separated by ";"
    let components = string.components(separatedBy: ";")
    guard components.count == 16 else { throw NSError(domain: "Matrix serialization", code: 400, userInfo: [ "dev_info": "Incorrect number of components for matrix. Expected 16, got \(components.count)" ]) }

    // Parse string compoenets to CGFloat values
    let values: [CGFloat] = components.compactMap {
        guard let doubleValueRepresentation = Double($0) else { return nil }
        return CGFloat(doubleValueRepresentation)
    }
    guard values.count == 16 else { throw NSError(domain: "Matrix serialization", code: 500, userInfo: [ "dev_info": "Unable to parse all values. \(components.count) out of 16 values were correctly paresed" ]) }

    // Generate and apply transform
    view.layer.transform = CATransform3D(m11: values[0], m12: values[1], m13: values[2], m14: values[3],
                                         m21: values[4], m22: values[5], m23: values[6], m24: values[7],
                                         m31: values[8], m32: values[9], m33: values[10], m34: values[11],
                                         m41: values[12], m42: values[13], m43: values[14], m44: values[15])
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...