Dynamic cell height for textView Swift

那年仲夏 提交于 2019-12-23 05:10:33

问题


I was using a label before and it was working fine. But I just realized I need a UITextView instead and I cant seem to get it working right.

The text just keeps going to the right and I can no longer see it. I need it to adjust to the dynamic height of the cell liked it worked before with the label.

struct postStruct {
    let username : String!
    let message : String!
    let photoURL : String!
    let timeStamp: String!
    let cellUserId : String!
}



class GeneralChatroom: UIViewController, UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate {

    @IBOutlet weak var messageTextField: UITextField!
    @IBOutlet weak var tableView: UITableView!

    var generalRoomDataArr = [postStruct]()



    override func viewDidLoad() {
        super.viewDidLoad()



        //Key Board - self delegate for return key
        messageTextField.delegate = self

        //TableView Cell word wrap (Dynamic Text)
        self.tableView.dataSource = self
        self.tableView.delegate = self
        self.tableView.estimatedRowHeight = 78
        self.tableView.rowHeight = UITableViewAutomaticDimension

        //Liquid Loader
        let growColor = UIColor.red
        let lineMatColor = UIColor(red: 11 / 255.0, green: 211 / 255.0, blue: 138 / 255.0, alpha: 1.0)
        let lineMatFrame = CGRect(x: self.view.frame.width * 0.5 - 25, y: 500, width: 50, height: 50)
        let lineMat = LiquidLoader(frame: lineMatFrame, effect: .Line(lineMatColor,4,1.0, growColor))

        //Placement of liquid Loader
        let screenSize = UIScreen.main.bounds
        let screenWidth = screenSize.width
       // let screenHeight = screenSize.height
        lineMat.frame = CGRect(x:screenWidth - 55 , y: 20, width:20 , height: 20)
        view.addSubview(lineMat)


        //Start Here


        let ref = FIRDatabase.database().reference()
        //let userID = FIRAuth.auth()?.currentUser?.uid







        ref.child("general_room").queryOrderedByKey().observe(.childAdded, with: {snapshot in

            let snapDict = snapshot.value as? NSDictionary
            let message = snapDict?["Message"] as? String ?? ""
            let username = snapDict?["user_name"] as? String ?? ""
            let userIDString = snapDict?["uid"] as? String ?? ""
            let firebaseUserPhotoURL = snapDict?["photo_url"] as? String ?? ""






//            print("username: " + username)
//            print("message: " + message)
//            print("URL: " + firebaseUserPhotoURL)
//            print("Snapshot" + snapshot.key)

            //Time String from Firbase Database
            let timeString = snapDict?["time_stamp"] as? String ?? "2017-03-06 00:20:51"

            //timeAgoSinceDate - Format and call function to recieve time of post
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
            let timeStampDate = dateFormatter.date(from: timeString)
            let timeStamp = timeAgoSinceDate(date: timeStampDate!, numericDates: false)


            //Assign array values
            self.generalRoomDataArr.insert(postStruct(username: username, message: message, photoURL: firebaseUserPhotoURL, timeStamp: timeStamp, cellUserId: userIDString), at: 0)
            self.tableView.reloadData()


        })


        //End Here


        self.tableView.reloadData()



    }//End ViewDidLoad





    //MARK:                      Buttons (BackButton || Send Button)


    @IBAction func backButtonPressed(_ sender: UIButton) {
        self.performSegue(withIdentifier: "BackToRoom", sender: nil)
    }


    //Message Send button is pressed data uploaded to firebase
    @IBAction func sendButtonPressed(_ sender: UIButton) {

        //If a character exists will be uploaded to firebase
        if ((messageTextField.text?.characters.count)! > 0) {

        let message : String = self.messageTextField.text!
        UploadGeneralChatRoom(message: message) //upload to general_room
        self.messageTextField.text = nil
        messageTextField.resignFirstResponder()//Quit keyboard

        self.tableView.reloadData() //Reload tableView
        //UploadUserData() //Update Rank in database

        }


    }




    //MARK:                     TableView (Cell & Labels)



    //Get Data of current cell that has been tapped
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        let userIdentityString = generalRoomDataArr[indexPath.row].cellUserId

        print("Uid of cell Data: " + userIdentityString!)
        print("section: \(indexPath.section)")
        print("row: \(indexPath.row)")

        //1.) If imageView touch is deteected
        //2.) Segua to new view controller by passing in the string UID(userIdentityString) of the cell
        //3.) Get database information based on the UID that is added(look at prevous methods)
        //      -might have to call this function and use separeate function
        //4.) Output data from database Users to represent a user profile



        //All you have to do is pass a UID (Check other Database methods to send UID)

    }


    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return generalRoomDataArr.count // your number of cell here
    }




    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        let cell = tableView.dequeueReusableCell(withIdentifier: "cell")

        //Transform Data From ^ to load at the bottom
        tableView.transform = CGAffineTransform (scaleX: 1,y: -1);
        cell?.contentView.transform = CGAffineTransform (scaleX: 1,y: -1);
        cell?.accessoryView?.transform = CGAffineTransform (scaleX: 1,y: -1);

        //Set username label to display username
        let usernameLabel = cell?.viewWithTag(1) as! UILabel
        usernameLabel.text = generalRoomDataArr[indexPath.row].username


        //Set message label to display message
//        let messageLabel = cell?.viewWithTag(2) as! UILabel
//        messageLabel.text = generalRoomDataArr[indexPath.row].message
//        messageLabel.numberOfLines = 0

        let messageLabel = cell?.viewWithTag(5) as! UITextView
        messageLabel.text = generalRoomDataArr[indexPath.row].message



        //initialize UI Profile Image
        let imageView = cell?.viewWithTag(3) as! UIImageView

        //Make Porfile Image Cirlce
        imageView.layer.cornerRadius = imageView.frame.size.width/2
        imageView.clipsToBounds = true

        //Set timeStampLabel to current time AGO
        let timeStampLabel = cell?.viewWithTag(4) as! UILabel
        timeStampLabel.text = generalRoomDataArr[indexPath.row].timeStamp
        timeStampLabel.numberOfLines = 0


        //Loading and change of Usesrs profile image on chat cell
        let userProfileChatImage = generalRoomDataArr[indexPath.row].photoURL

        //Load profile image(on cell) with URL & Alamofire Library
            let downloadURL = NSURL(string: userProfileChatImage!)
            imageView.af_setImage(withURL: downloadURL as! URL)

        return cell!
    }




    //MARK:              KeyBoard close on return button


    // Hide the keyboard when the return key pressed
    func textFieldShouldReturn(_ messageTextField: UITextField) -> Bool {
        messageTextField.resignFirstResponder()
        return true
    }




}//END CLASS

回答1:


set the height of textView and connect it to view controller as NSLayoutConstraints and update it via the textViewDidChange.

See the below code in which textViewHeight is the NSLayoutConstraints

func textViewDidChange(_ textView: UITextView) {

    let fixedWidth = textView.frame.size.width
    textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
    var newFrame = textView.frame
    newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
    textView.frame = newFrame;
    textViewHeight.constant = newFrame.size.height
    tableView.beginUpdates()
    tableView.endUpdates()
}



回答2:


Did you try changing the size from textView delegate methods? Perhaps something like this:

func textViewDidChange(_ textView: UITextView) {
    let currentOffset = tableView.contentOffset
    UIView.setAnimationsEnabled(false)
    tableView.beginUpdates()
    tableView.endUpdates()
    UIView.setAnimationsEnabled(true)
    tableView.setContentOffset(currentOffset, animated: false)
}

I used this code to adjust a cell's height as the user typed into the textview. Not sure if it will work for your purposes but give it a shot.



来源:https://stackoverflow.com/questions/43398867/dynamic-cell-height-for-textview-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!