我在Swift的iOS上这样做。我试图只是简单地更新它的框架来动画UIView。我创建了一个UITextField的自定义子类。我的代码如下。
import Foundation
import UIKit
enum TextFieldState {
case Active
case InactiveBlank
case InactiveText
}
/**
Use this class to create any text field in the New workout VC
*/
class TextField: UITextField {
// MARK: Properties
/// The color for all accent elements
private let standardColor: UIColor = Color().blue
/// The color for all error elements
private let errorColor: UIColor = Color().red
/// The font for inactive state
private let inactiveFont: UIFont = Fonts.Regular().sixteen
/// The font for active state
private let activeFont: UIFont = Fonts.Bold().thirtySix
/// The font for hint active state
private let activeHintFont: UIFont = Fonts.Regular().sixteen
/// The font for hint in inactive state
private let inactiveHintFont: UIFont = Fonts.Regular().twelve
/// The placeholder and hint for the text field
let placeholderText: String
/// The type of the field
let type: TextFieldType
/// The bottom line for the text field
var bottomLine: UIView { return self.createBottomLine() }
/// The placeholder for the field
var placeholderLabel: UILabel { return self.createPlaceholderLabel() }
/// The rect for editing and text bounds
private var textBounds: Rect {
return Rect(x: 0, y: 31, w: self.frame.w, h: 96)
}
/// The variable for the text of the text field
// MARK: Initializers
/// Default initalizer
init<A: TextFieldOptions>(frame: CGRect, options: A) {
// Set the placeholder text value
self.placeholderText = options.placeHolderText
// Set the type of the text field
self.type = options.type
// Call the super initalizer
super.init(frame: frame)
// Update settings based on type
self.styleType()
// Set the delgate for the text field
self.delegate = self
// Set the background color
self.backgroundColor = Color().white
// Set the font for the text field
self.font = self.activeFont
// Layout all the views
self.layoutViews()
}
/// Required by Apple NEVER USE
required init?(coder aDecoder: NSCoder) {
fatalError("This class doesn't support NSCoding")
}
// MARK: Functions
private func layoutViews() {
// Add the placeholder text to the text field
self.addSubview(self.placeholderLabel)
// Add the bottom line to the text field
self.addSubview(self.bottomLine)
}
private func styleType() {
if self.type == .All {
self.returnKeyType = .Next
self.autocorrectionType = .No
}
}
private func createBottomLine() -> UIView {
// Get the y position for the line
let y: CGFloat = self.placeholderLabel.frame.origin.y + self.placeholderLabel.frame.height + 4
// Create the frame for the bottom line
let bottomLineFrame: Rect = Rect(x: 0, y: y , w: self.frame.w, h: 1)
// Create the bottom line
let botttomLine: Line = Line(frame: bottomLineFrame, alpha: 0.38)
// Return the bottom line
return botttomLine
}
private func createPlaceholderLabel() -> UILabel {
// Create the frame for the placeholder text
let placeholderFrame: CGRect = CGRect(x: 0, y: 20, width: self.frame.width, height: 19)
// Create the placeholder text
let placeHolder: UILabel = UILabel(frame: placeholderFrame, font: self.inactiveFont, align: .Left, color: Color().black)
// Set the alpha for the placeholder
placeHolder.alpha = 0.38
// Set the text for the placeholder
placeHolder.text = self.placeholderText
// Return the placeholder
return placeHolder
}
/**
This function updates the style for the text field
- parameter state: The state that the text field is current
*/
private func updateStyle(state: TextFieldState) {
switch state {
case .Active:
self.activeStyle()
case .InactiveBlank:
print("Update inactive blank for state & style changes")
case .InactiveText:
print("Update inactive text for state and style changes")
}
}
/**
This function is for when a text field is in an active state and needs to be style accordingly
*/
private func activeStyle() {
// Create the animation
let animate: () -> () = {
print("ANIMATE!!!")
self.placeholderLabel.font = self.activeHintFont
self.placeholderLabel.frame.origin.y = 4
self.placeholderLabel.textColor = self.standardColor
self.bottomLine.backgroundColor = self.standardColor
var newFrame: CGRect = self.bottomLine.frame
newFrame.origin.y = 86
self.bottomLine.frame = newFrame
}
// Animate the view
UIView.animateWithDuration(0.3, animations: animate)
UIView.animateWithDuration(0.3, delay: 0.0, options: .CurveEaseInOut, animations: {
self.bottomLine.frame.origin.y = 86
}, completion: nil)
}
}
// MARK: Methods for text placement
extension TextField {
override func editingRectForBounds(bounds: CGRect) -> CGRect {
return textBounds
}
override func textRectForBounds(bounds: CGRect) -> CGRect {
return textBounds
}
}
// MARK: All delegate methods
extension TextField : UITextFieldDelegate {
/**
This function handles when the text field begins editing
*/
func textFieldDidBeginEditing(textField: UITextField) {
print("I started editing")
self.updateStyle(.Active)
}
/**
This function handles when the text field finishes editing
*/
func textFieldDidEndEditing(textField: UITextField) {
print("I finished editing")
}
/**
This function handles when the text field changes
*/
func textFieldDidChange(textField: TextField) {
print("I changed")
print("Text = \(self.text)")
}
}
动画块被调用但没有更新。该视图已在屏幕上,我知道viewWillApear
已被调用。什么可能导致这类问题?我已经尝试将动画传递到另一个线程,但这不起作用。
答案 0 :(得分:3)
这是设置帧y位置的逻辑。只能使用视图的框架设置器设置框架。
let newFrame: CGRect = self.bottomLine.frame;
newFrame.origin.y = 86;
self.bottomLine.frame = newFrame;
编辑在动画播放之前,将重新调用bottomLine初始值设定项。该视图的延迟构建(通过分配标记)是一种很好的方法。
答案 1 :(得分:0)
试试这个:
self.bottomLine.frame = CGRect(x: self.bottomLine.frame.origin.x,
y: 86,
width: self.bottomLine.frame.size.width,
height: self.bottomLine.frame.size.height)
答案 2 :(得分:0)
这是动画观看位置的方式,请尝试以下
self.bottomLine.frame.origin.y = 86
UIView.animateWithDuration(0.3, delay: 0.0, options: .CurveEaseInOut, animations: {
self.layoutIfNeeded()
}, completion: nil)
答案 3 :(得分:-2)
它正在尝试使用延迟时间
UIView.animateWithDuration(0.4, delay: 2.0, options: .CurveEaseInOut, animations: {
self.bottomLine.frame.origin.y = 86
}, completion: nil)