UICollectionViewFlowLayout与collectionview和textfields有关

时间:2017-04-26 18:19:09

标签: swift uicollectionview uicollectionviewcell uicollectionviewlayout uitextfielddelegate

我有一个应用程序,它使用一个水平滚动的集合视图,并在其中包含collectionviewcells。一切都很顺利,直到我尝试使用textfielddelegate实现一个包含2个文本字段的登录/注册单元格。当我按下其中一个文本字段时,键盘会显示一瞬间然后隐藏。在它执行此操作之后,视图被按下一点点,如果我再次按下文本字段,它会被向上推,不会下降。以下是一些截图:

before touching a textfieldafter I touch a textfield

我收到各种UICollectionViewFlowLayout错误,要求我在UICollectionViewFlowLayoutBreakForInvalidSizes处创建符号断点。

The behavior of the UICollectionViewFlowLayout is not defined because: 2017-04-26 13:55:03.199199-0400 Eyetube[1500:243622] the item height must be less than the height of the UICollectionView minus the section insets top and bottom values, minus the content insets top and bottom values. 2017-04-26 13:55:03.200490-0400 Eyetube[1500:243622] The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x10453ee90>, and it is attached to <UICollectionView: 0x104806800; frame = (0 0; 768 960); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x17405a610>; layer = <CALayer: 0x17002f0a0>; contentOffset: {2304, 0}; contentSize: {3072, 910}> collection view layout: <UICollectionViewFlowLayout: 0x10453ee90>. 2017-04-26 13:55:03.200575-0400 Eyetube[1500:243622] Make a symbolic breakpoint at UICollectionViewFlowLayoutBreakForInvalidSizes to catch this in the debugger.

我尝试过多次调试,但是找不到错误的确切位置并没有太大帮助。我已经被困在这个问题上好几个小时了,似乎无法解决这个问题。

我在collectionviewcontroller中初始化布局的地方:

func setupCollectionView() {

    if let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
        flowLayout.scrollDirection = .horizontal
        flowLayout.minimumLineSpacing = 0
    }

    collectionView?.backgroundColor = UIColor.white
    collectionView?.register(VideoFeedCell.self, forCellWithReuseIdentifier: cellId)
    collectionView?.register(ChannelFeedCell.self, forCellWithReuseIdentifier: channelCellId)
    collectionView?.register(ARFeedCell.self, forCellWithReuseIdentifier: augmentedRealityCellId)
    collectionView?.register(LoginRegisterCell.self, forCellWithReuseIdentifier: loginRegisterCellId)

    collectionView?.contentInset = UIEdgeInsetsMake(0, 0, 50, 0)
    collectionView?.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 50, 0)

    collectionView?.isPagingEnabled = true

}

我的sizeForItemAt func,也在我的collectionviewcontroller中(PS,我从高处减去50,因为我添加了作为视图的子视图的底部菜单栏。我也因为这个而更改了collectionview的contentInset和scrollIndicatorInsets):< / p>

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let cellSize = CGSize(width: view.frame.width, height: view.frame.height - 50)

    return cellSize
}

以下是collectionviewcell的完整代码,我遇到了问题:

import UIKit

class LoginRegisterCell:BaseCell,UITextFieldDelegate {

let logoImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.image = UIImage(named: "eyetube_logo_font")
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.contentMode = .scaleAspectFit
    return imageView
}()

let emailTextField: LeftPaddedTextField = {
    let tf = LeftPaddedTextField()
    tf.keyboardType = .emailAddress
    tf.placeholder = "Enter email"
    tf.substituteFontName = "SourceSansPro-Regular"
    tf.layer.borderColor = UIColor.rgb(220, green: 220, blue: 220).cgColor
    tf.layer.borderWidth = 1
    tf.translatesAutoresizingMaskIntoConstraints = false
    return tf
}()

let passwordTextField: LeftPaddedTextField = {
    let tf = LeftPaddedTextField()
    tf.placeholder = "Enter password"
    tf.substituteFontName = "SourceSansPro-Regular"
    tf.layer.borderColor = UIColor.rgb(220, green: 220, blue: 220).cgColor
    tf.layer.borderWidth = 1
    tf.isSecureTextEntry = true
    tf.translatesAutoresizingMaskIntoConstraints = false
    return tf
}()

lazy var loginButton: UIButton = {
    let button = UIButton(type: .system)
    button.backgroundColor = UIColor.rgb(225, green: 31, blue: 40)
    button.titleLabel?.font = UIFont(name: "SourceSansPro-SemiBold", size: 20)
    button.setTitle("Log In", for: .normal)
    button.setTitleColor(UIColor.white, for: .normal)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.addTarget(self, action: #selector(handleLogin), for: .touchUpInside)

    return button
}()

lazy var registerLink: UIButton = {
    let button = UIButton(type: .system)
    button.setTitle("Don't have an account? Register here", for: .normal)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.titleLabel?.font = UIFont(name: "SourceSansPro-Regular", size: 18)
    button.setTitleColor(UIColor.darkGray, for: .normal)
    let underlineAttribute = [NSUnderlineStyleAttributeName: NSUnderlineStyle.styleSingle.rawValue]
    let underlineAttributedString = NSAttributedString(string: (button.titleLabel?.text)!, attributes: underlineAttribute)
    button.titleLabel?.attributedText = underlineAttributedString
    button.addTarget(self, action: #selector(handleRegister), for: .touchUpInside)

    return button
}()

var containerView: UIView!

override func setupViews() {
    super.setupViews()

    self.emailTextField.delegate = self
    emailTextField.returnKeyType = .next
    self.passwordTextField.delegate = self
    passwordTextField.returnKeyType = .done

    containerView = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height))
    containerView.backgroundColor = .green
    addSubview(containerView)

    containerView.addSubview(logoImageView)
    containerView.addSubview(emailTextField)
    containerView.addSubview(passwordTextField)
    containerView.addSubview(loginButton)
    containerView.addSubview(registerLink)

    setupLogoImageView()
    setupInputs()
    setupLoginButton()
    setupRegisterLink()
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}

func handleLogin() {

    //first check if the email/password textfields are empty or not
    guard let email = emailTextField.text , !email.isEmpty else {
        let alert = UIAlertView (title: "Invalid Email", message: "Please enter an email to log in", delegate: self, cancelButtonTitle: "OK")
            alert.show()
        return
    }

    guard let password = passwordTextField.text , !password.isEmpty else {
        let alert = UIAlertView (title: "Invalid Password", message: "Please enter a password to log in", delegate: self, cancelButtonTitle: "OK")
            alert.show()
        return
    }

    //create session here
    ApiLoginAuthentication.sharedInstance.login_now(username: email, password: password, onCompletion: {(loginSuccessful: Bool) -> Void in

        guard (loginSuccessful) else {
            DispatchQueue.main.async {
                let alert = UIAlertView (title: "Invalid Account info", message: "The account information entered is invalid. Please log in with a valid account.", delegate: self, cancelButtonTitle: "OK")
                alert.show()
            }
            return
        }

        DispatchQueue.main.async {
            self.emailTextField.text = ""
            self.passwordTextField.text = ""
        }
        print("the login was successful")
    })
        /**
        let profileUrl: String = "https://eyetube.net/user/profile.asp"
        ApiLoginAuthentication.sharedInstance.getContent(contentUrl: profileUrl, onCompletion: {(responseString: String, isLoggedIn: Bool) -> Void in
            print(responseString)
            print("user status: \(isLoggedIn)")

            let json: Any?
            do {
                let data: NSData = responseString.data(using: String.Encoding.utf8)! as NSData
                json = try JSONSerialization.jsonObject(with: data as Data, options: .allowFragments)
                print(json)
            } catch let error {
                print("error: \(error)")
            }
        })**/
}

func handleRegister() {
    let eyetubeRegisterLink = "https://eyetube.net/user/register.asp?rUrl="
    UIApplication.shared.openURL(URL(string: eyetubeRegisterLink)!)
}

func setupLogoImageView() {
    var sizeConstant: CGFloat!
    var centerYConstant: CGFloat!
    if UI_USER_INTERFACE_IDIOM() == .pad {
        sizeConstant = 400
        centerYConstant = -260
    } else {
        sizeConstant = 200
        centerYConstant = -160
    }
    NSLayoutConstraint(item: logoImageView, attribute: .centerY, relatedBy: .equal, toItem: containerView, attribute: .centerY, multiplier: 1, constant: centerYConstant!).isActive = true
    NSLayoutConstraint(item: logoImageView, attribute: .centerX, relatedBy: .equal, toItem: containerView, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: logoImageView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: sizeConstant).isActive = true
    NSLayoutConstraint(item: logoImageView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: sizeConstant).isActive = true
}

func setupInputs() {
    var widthConstant: CGFloat!
    var leftConstant: CGFloat!
    if UI_USER_INTERFACE_IDIOM() == .pad {
        widthConstant = -64
        leftConstant = 32
    } else {
        widthConstant = -32
        leftConstant = 16
    }
    NSLayoutConstraint(item: emailTextField, attribute: .top, relatedBy: .equal, toItem: logoImageView, attribute: .bottom, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: emailTextField, attribute: .left, relatedBy: .equal, toItem: containerView, attribute: .left, multiplier: 1, constant: leftConstant).isActive = true
    NSLayoutConstraint(item: emailTextField, attribute: .width, relatedBy: .equal, toItem: containerView, attribute: .width, multiplier: 1, constant: widthConstant).isActive = true
    NSLayoutConstraint(item: emailTextField, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 50).isActive = true

    NSLayoutConstraint(item: passwordTextField, attribute: .top, relatedBy: .equal, toItem: emailTextField, attribute: .bottom, multiplier: 1, constant: 8).isActive = true
    NSLayoutConstraint(item: passwordTextField, attribute: .left, relatedBy: .equal, toItem: containerView, attribute: .left, multiplier: 1, constant: leftConstant).isActive = true
    NSLayoutConstraint(item: passwordTextField, attribute: .width, relatedBy: .equal, toItem: containerView, attribute: .width, multiplier: 1, constant: widthConstant).isActive = true
    NSLayoutConstraint(item: passwordTextField, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 50).isActive = true
}

func setupLoginButton() {
    NSLayoutConstraint(item: loginButton, attribute: .centerX, relatedBy: .equal, toItem: containerView, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: loginButton, attribute: .top, relatedBy: .equal, toItem: passwordTextField, attribute: .bottom, multiplier: 1, constant: 16).isActive = true
    NSLayoutConstraint(item: loginButton, attribute: .width, relatedBy: .equal, toItem: passwordTextField, attribute: .width, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: loginButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 50).isActive = true
}

func setupRegisterLink() {
    NSLayoutConstraint(item: registerLink, attribute: .centerX, relatedBy: .equal, toItem: containerView, attribute: .centerX, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: registerLink, attribute: .top, relatedBy: .equal, toItem: loginButton, attribute: .bottom, multiplier: 1, constant: 12).isActive = true
    NSLayoutConstraint(item: registerLink, attribute: .width, relatedBy: .equal, toItem: loginButton, attribute: .width, multiplier: 1, constant: 0).isActive = true
    NSLayoutConstraint(item: registerLink, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: 40).isActive = true
}

}

0 个答案:

没有答案