当 KILabel 或 ActiveLabel 没有字符串时,将其高度设置为 0。但原始 UILabel 工作正常
Posted
技术标签:
【中文标题】当 KILabel 或 ActiveLabel 没有字符串时,将其高度设置为 0。但原始 UILabel 工作正常【英文标题】:Set the KILabel or ActiveLabel's height to 0 when it has no string. But Original UILabel is working fine 【发布时间】:2016-08-23 16:34:37 【问题描述】:这个问题与UITableView和UILabel的高度有关。
您好,我正在使用自动布局来设置行中的动态高度。
这是我在表格单元格中的布局。
描述标签
LikeCountLabel 为蓝色“1”
评论标签
时间表是灰色的“标签”
时间标签
我还检查了 UILabel 的属性
import UIKit
import Parse
class ShopDetailCell: UITableViewCell
@IBOutlet weak var commentBtn: UIButton!
@IBOutlet weak var likeBtn: UIButton!
@IBOutlet weak var profileImg: UIImageView!
@IBOutlet weak var postImg: UIImageView!
@IBOutlet weak var moreBtn: UIButton!
@IBOutlet weak var userNameBtn: UIButton!
@IBOutlet weak var uuidLabel: UILabel!
@IBOutlet weak var descriptionLabel: KILabel!
@IBOutlet weak var likesLabel: UILabel!
@IBOutlet weak var commentLabel: KILabel!
@IBOutlet weak var dateLabel: UILabel!
我的 TableView 控制器
import UIKit
import Parse
import SDWebImage
class FeedVC: UITableViewController
//UI Objects
@IBOutlet weak var indicator: UIActivityIndicatorView!
var refresher=UIRefreshControl()
//arrays to hold server data
var profileArray = [PFFile]()
var usernameArray = [String]()
var dateArray = [NSDate?]()
var postArray = [PFFile]()
var uuidArray = [String]()
var descriptionArray = [String]()
var commentsArray = [String]()
var isLoadedView:Bool = false
var sellingArray = [Bool]()
var followArray = [String]()
//advertise
var advArray = [PFFile]()
//page size
var page : Int = 10
//Default func
override func viewDidLoad()
super.viewDidLoad()
//background color
tableView?.backgroundColor = UIColor(red: 0.0 / 255.0, green: 0.0 / 255.0, blue: 0.0 / 255.0, alpha: 1)
//automatic row height
tableView.estimatedRowHeight = 450
tableView.rowHeight = UITableViewAutomaticDimension
//pull to refresh
refresher.addTarget(self, action: #selector(FeedVC.loadPosts), forControlEvents: UIControlEvents.ValueChanged)
tableView.addSubview(refresher)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(FeedVC.refresh), name: "liked", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(FeedVC.uploaded(_:)), name: "Uploaded", object: nil)
self.navigationController?.setNavigationBarHidden(true, animated: true)
//calling function to load posts
loadPosts()
//receive notification from UploadViewController
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(FeedVC.scrollToFirstRow(_:)), name: "scrollToTop", object: nil)
func scrollToFirstRow(notification:NSNotification)
if isLoadedView == true
print("scrollToTop!!!!!")
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
// reloading func with posts after received notification
func uploaded(notification:NSNotification)
print("receicev")
loadPosts()
//refresh function
func refresh()
self.tableView.reloadData()
// load posts
func loadPosts()
//STEP 1. Find posts related to people who we are following
let followQuery = PFQuery(className: "fans")
followQuery.whereKey("myfans", equalTo: PFUser.currentUser()!.username!)
followQuery.findObjectsInBackgroundWithBlock ( (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil
//clean up
self.followArray.removeAll(keepCapacity: false)
//Appending where people following..
//find related objects
for object in objects!
self.followArray.append(object.objectForKey("fan") as! String)
//append current user to see own posts in feed
self.followArray.append(PFUser.currentUser()!.username!)
//STEP 2. Find posts made by people appended to followArray
let query = PFQuery(className: "posts")
query.whereKey("username", containedIn: self.followArray)
query.limit = self.page
query.addDescendingOrder("createdAt")
query.findObjectsInBackgroundWithBlock( (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil
//clean up
self.usernameArray.removeAll(keepCapacity: false)
self.profileArray.removeAll(keepCapacity: false)
self.dateArray.removeAll(keepCapacity: false)
self.postArray.removeAll(keepCapacity: false)
self.descriptionArray.removeAll(keepCapacity: false)
self.uuidArray.removeAll(keepCapacity: false)
//find related objects
for object in objects!
self.usernameArray.append(object.objectForKey("username") as! String)
self.profileArray.append(object.objectForKey("profileImg") as! PFFile)
self.dateArray.append(object.createdAt)
self.postArray.append(object.objectForKey("postImg") as! PFFile)
self.descriptionArray.append(object.objectForKey("title") as! String)
self.uuidArray.append(object.objectForKey("uuid") as! String)
//reload tableView & end spinning of refresher
self.tableView.reloadData()
self.refresher.endRefreshing()
else
print(error!.localizedDescription)
)
else
print(error!.localizedDescription)
)
//scrolled down
override func scrollViewDidScroll(scrollView: UIScrollView)
if scrollView.contentOffset.y >= scrollView.contentSize.height - self.view.frame.size.height * 2
loadMore()
// pagination
func loadMore()
//if posts on the server are more than shown
if page <= uuidArray.count
//start animating indicator
indicator.startAnimating()
//increase page size to load + 10 posts
page = page + 10
//STEP 1. Find posts related to people who we are following
let followQuery = PFQuery(className: "fans")
followQuery.whereKey("myfans", equalTo: PFUser.currentUser()!.username!)
followQuery.findObjectsInBackgroundWithBlock ( (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil
//clean up
self.followArray.removeAll(keepCapacity: false)
//Appending where people following..
//find related objects
for object in objects!
self.followArray.append(object.objectForKey("fan") as! String)
//append current user to see own posts in feed
self.followArray.append(PFUser.currentUser()!.username!)
//STEP 2. Find posts made by people appended to followArray
let query = PFQuery(className: "posts")
query.whereKey("username", containedIn: self.followArray)
query.limit = self.page
query.addDescendingOrder("createdAt")
query.findObjectsInBackgroundWithBlock( (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil
//clean up
self.usernameArray.removeAll(keepCapacity: false)
self.profileArray.removeAll(keepCapacity: false)
self.dateArray.removeAll(keepCapacity: false)
self.postArray.removeAll(keepCapacity: false)
self.descriptionArray.removeAll(keepCapacity: false)
self.uuidArray.removeAll(keepCapacity: false)
//find related objects
for object in objects!
self.usernameArray.append(object.objectForKey("username") as! String)
self.profileArray.append(object.objectForKey("profileImg") as! PFFile)
self.dateArray.append(object.createdAt)
self.postArray.append(object.objectForKey("postImg") as! PFFile)
self.descriptionArray.append(object.objectForKey("title") as! String)
self.uuidArray.append(object.objectForKey("uuid") as! String)
//reload tableView stop indicator animation
self.tableView.reloadData()
self.indicator.stopAnimating()
else
print(error!.localizedDescription)
)
else
print(error!.localizedDescription)
)
//number of cell
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return uuidArray.count + 1
// cell config
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
// 가장 첫 페이지는 광고영역..
if indexPath.row == 0
let cell = tableView.dequeueReusableCellWithIdentifier("AdvertiseCell", forIndexPath: indexPath) as! AdvertiseCell
return cell
//define cell
let cell = tableView.dequeueReusableCellWithIdentifier("ShopDetailCell", forIndexPath: indexPath) as! ShopDetailCell
cell.userNameBtn.setTitle(usernameArray[indexPath.row - 1], forState: UIControlState.Normal)
cell.userNameBtn.sizeToFit()
cell.uuidLabel.text = uuidArray[indexPath.row - 1]
cell.descriptionLabel.text = descriptionArray[indexPath.row - 1]
cell.descriptionLabel.sizeToFit()
// manipulate like button depending on did user like it or not
let isComments = PFQuery(className: "comments")
isComments.whereKey("to", equalTo: cell.uuidLabel.text!)
isComments.limit = 1
isComments.addAscendingOrder("createdAt")
isComments.countObjectsInBackgroundWithBlock((count:Int32, error:NSError?) -> Void in
//if no any likes are found, else found likes
if count==0
cell.commentLabel.text = nil
cell.commentLabel.sizeToFit()
// cell.commentHeight.constant = 0
else
//STEP 2. Request last (page size 15) comments
let query = PFQuery(className: "comments")
query.whereKey("to", equalTo: cell.uuidLabel.text!)
query.limit = 1
query.addDescendingOrder("createdAt")
query.findObjectsInBackgroundWithBlock((objects:[PFObject]?, error:NSError?) -> Void in
if error == nil
//find related object
for object in objects!
let comment = object.objectForKey("comment") as! String
let by = object.objectForKey("username") as! String
let commentString = by + " " + comment
let boldString = NSMutableAttributedString(string: commentString)
boldString.addAttribute(NSFontAttributeName, value: UIFont(name: "SFUIText-Bold", size: 14)!, range: NSRange(0...by.characters.count))
cell.commentLabel.attributedText = boldString
cell.commentLabel.sizeToFit()
// self.tableView?.reloadData()
else
print(error?.localizedDescription)
)
)
//STEP 1. Load data of guest
let profileImgQuery = PFQuery(className: "_User")
profileImgQuery.whereKey("username", equalTo: usernameArray[indexPath.row - 1])
profileImgQuery.findObjectsInBackgroundWithBlock((objects:[PFObject]?, error:NSError?) -> Void in
if error == nil
//shown wrong user
if objects!.isEmpty
print("Wrong User")
//find related to user information
for object in objects!
//Set Image
let profilePictureObject = object.objectForKey("profileImg") as? PFFile
profilePictureObject?.getDataInBackgroundWithBlock (imageData:NSData?, error:NSError?) -> Void in
if(imageData != nil)
let profileURL : NSURL = NSURL(string: profilePictureObject!.url!)!
cell.profileImg.sd_setImageWithURL(profileURL, placeholderImage: UIImage(named: "holderImg"))
else
print(error?.localizedDescription)
)
// place post picture using the sdwebimage
let postURL : NSURL = NSURL(string: postArray[indexPath.row - 1].url!)!
cell.postImg.sd_setImageWithURL(postURL, placeholderImage: UIImage(named: "holderImg"))
//Calculate post date
let from = dateArray[indexPath.row - 1]
let now = NSDate()
let components : NSCalendarUnit = [.Second, .Minute, .Hour, .Day, .WeekOfMonth]
let difference = NSCalendar.currentCalendar().components(components, fromDate: from!, toDate: now, options: [])
// logic what to show : Seconds, minutes, hours, days, or weeks
if difference.second <= 0
cell.dateLabel.text = "NOW"
if difference.second > 0 && difference.minute == 0
cell.dateLabel.text = "\(difference.second) SEC AGO"
if difference.minute > 0 && difference.hour == 0
cell.dateLabel.text = "\(difference.minute) MIN AGO"
if difference.hour > 0 && difference.day == 0
cell.dateLabel.text = "\(difference.hour) HR AGO"
if difference.day > 0 && difference.weekOfMonth == 0
cell.dateLabel.text = "\(difference.day) DAY AGO"
if difference.weekOfMonth > 0
cell.dateLabel.text = "\(difference.weekOfMonth) WEEK AGO"
//
//
// manipulate like button depending on did user like it or not
let didLike = PFQuery(className: "likes")
didLike.whereKey("by", equalTo: PFUser.currentUser()!.username!)
didLike.whereKey("to", equalTo: cell.uuidLabel.text!)
didLike.countObjectsInBackgroundWithBlock((count:Int32, error:NSError?) -> Void in
//if no any likes are found, else found likes
if count==0
cell.likeBtn.setTitle("unlike", forState: .Normal)
cell.likeBtn.setBackgroundImage(UIImage(named:"heartBtn"), forState: .Normal)
else
cell.likeBtn.setTitle("like", forState: .Normal)
cell.likeBtn.setBackgroundImage(UIImage(named: "heartTapBtn"), forState: .Normal)
)
//count total likes of shown post
let countLikes = PFQuery(className: "likes")
countLikes.whereKey("to", equalTo: cell.uuidLabel.text!)
countLikes.countObjectsInBackgroundWithBlock((count:Int32, error:NSError?) -> Void in
cell.likesLabel.text="\(count) likes"
)
//asign index
cell.userNameBtn.layer.setValue(indexPath, forKey: "index")
cell.commentBtn.layer.setValue(indexPath, forKey: "index")
cell.moreBtn.layer.setValue(indexPath, forKey: "index")
// @mention is tapped
cell.descriptionLabel.userHandleLinkTapHandler = label, handle, rang in
var mention = handle
mention = String(mention.characters.dropFirst())
if mention.lowercaseString == PFUser.currentUser()?.username
let home = self.storyboard?.instantiateViewControllerWithIdentifier("MyShopCollectionVC") as! MyShopCollectionVC
self.navigationController?.pushViewController(home, animated: true)
else
guestname.append(mention.lowercaseString)
let guest = self.storyboard?.instantiateViewControllerWithIdentifier("GuestShopCollectionVC") as! GuestShopCollectionVC
self.navigationController?.pushViewController(guest, animated: true)
// #Hashtag is tapped
cell.descriptionLabel.hashtagLinkTapHandler = label, handle, range in
var mention = handle
mention = String(mention.characters.dropFirst())
hashtag.append(mention.lowercaseString)
let hashvc = self.storyboard?.instantiateViewControllerWithIdentifier("HashTagsCollectionVC") as! HashTagsCollectionVC
self.navigationController?.pushViewController(hashvc, animated: true)
// cell.layoutIfNeeded()
return cell
////////
@IBAction func userNameBtnTapped(sender: AnyObject)
//call index of button
let i = sender.layer.valueForKey("index") as! NSIndexPath
//call cell to call further cell data
let cell = tableView.cellForRowAtIndexPath(i) as! ShopDetailCell
//if user tapped on himeself go home, else go guest
if cell.userNameBtn.titleLabel?.text == PFUser.currentUser()?.username
let home = self.storyboard?.instantiateViewControllerWithIdentifier("MyShopCollectionVC") as! MyShopCollectionVC
self.navigationController?.pushViewController(home, animated: true)
else
guestname.append(cell.userNameBtn.titleLabel!.text!)
let guest = self.storyboard?.instantiateViewControllerWithIdentifier("GuestShopCollectionVC") as! GuestShopCollectionVC
self.navigationController?.pushViewController(guest, animated: true)
@IBAction func commentBtnTapped(sender: AnyObject)
print("commentTapped")
// call index of button
let i = sender.layer.valueForKey("index") as! NSIndexPath
// call cell to call further cell data
let cell = tableView.cellForRowAtIndexPath(i) as! ShopDetailCell
//send related data to global variables
commentUUID.append(cell.uuidLabel.text!)
// commentOwner.append(cell.userNameLabel.titleLabel!.text!)
commentOwner.append(cell.userNameBtn.titleLabel!.text!)
let comment = self.storyboard?.instantiateViewControllerWithIdentifier("CommentVC") as! CommentVC
self.navigationController?.pushViewController(comment, animated: true)
@IBAction func moreBtnTapped(sender: AnyObject)
let i = sender.layer.valueForKey("index") as! NSIndexPath
//Call cell to call further cell date
let cell = tableView.cellForRowAtIndexPath(i) as! ShopDetailCell
//Delete Action
let delete = UIAlertAction(title: "Delete", style: .Default) (UIAlertAction) -> Void in
//STEP 1. Delete row from tablevIEW
self.usernameArray.removeAtIndex(i.row)
self.profileArray.removeAtIndex(i.row)
self.dateArray.removeAtIndex(i.row)
self.postArray.removeAtIndex(i.row)
self.descriptionArray.removeAtIndex(i.row)
self.uuidArray.removeAtIndex(i.row)
//STEP 2. Delete post from server
let postQuery = PFQuery(className: "posts")
postQuery.whereKey("uuid", equalTo: cell.uuidLabel.text!)
postQuery.findObjectsInBackgroundWithBlock( (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil
for object in objects!
object.deleteInBackgroundWithBlock( (success:Bool, error:NSError?) -> Void in
if success
//send notification to rootViewController to update shown posts
NSNotificationCenter.defaultCenter().postNotificationName("uploaded", object: nil)
//push back
self.navigationController?.popViewControllerAnimated(true)
else
print(error?.localizedDescription)
)
else
print(error?.localizedDescription)
)
//STEP 2. Delete likes of post from server
let likeQuery = PFQuery(className: "likes")
likeQuery.whereKey("to", equalTo: cell.uuidLabel.text!)
likeQuery.findObjectsInBackgroundWithBlock( (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil
for object in objects!
object.deleteEventually()
)
//STEP 3. Delete comments of post from server
let commentQuery = PFQuery(className: "comments")
commentQuery.whereKey("to", equalTo: cell.uuidLabel.text!)
commentQuery.findObjectsInBackgroundWithBlock( (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil
for object in objects!
object.deleteEventually()
)
//STEP 4. Delete hashtags of post from server
let hashtagQuery = PFQuery(className: "hashtags")
hashtagQuery.whereKey("to", equalTo: cell.uuidLabel.text!)
hashtagQuery.findObjectsInBackgroundWithBlock( (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil
for object in objects!
object.deleteEventually()
)
//Complain Action
let complain = UIAlertAction(title: "Complain", style: .Default) (UIAlertAction) -> Void in
//send complain to server
let complainObj = PFObject(className: "complain")
complainObj["by"] = PFUser.currentUser()?.username
complainObj["to"] = cell.uuidLabel.text
complainObj["owner"] = cell.userNameBtn.titleLabel?.text
complainObj.saveInBackgroundWithBlock( (success:Bool, error:NSError?) -> Void in
if success
self.alert("Complain has been made successfully", message: "Thank You! We will consider your complain")
else
self.alert("ERROR", message: error!.localizedDescription)
)
//Cancel ACTION
let cancel = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
//create menu controller
let menu = UIAlertController(title: "Menu", message: nil, preferredStyle: .ActionSheet)
//if post belongs to user
if cell.userNameBtn.titleLabel?.text == PFUser.currentUser()?.username
menu.addAction(delete)
menu.addAction(cancel)
else
menu.addAction(complain)
menu.addAction(cancel)
//show menu
self.presentViewController(menu, animated: true, completion: nil)
//alert action
func alert(title: String, message:String)
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
let ok = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alert.addAction(ok)
presentViewController(alert, animated: true, completion: nil)
好吧,我的问题是……如果 UILabel 的字符串是 nil 或 "" 那么它的高度应该设置为零。表格单元格的高度也小于原始高度。
UILabel 没有字符串,但它仍然有高度。
【问题讨论】:
嘿,你找到解决办法了吗?因为我面临同样的问题 【参考方案1】:似乎这是KILabel
库中的问题,解决方案是(link)创建自定义标签类,继承自KILabel
并覆盖此方法:
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines
if (self.text.length == 0)
return CGRectZero;
return [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
【讨论】:
【参考方案2】:像这样声明你的UILabel
高度约束:-
@IBOutlet weak var likeLabelHeightConstraint: NSLayoutConstraint!
然后像这样设置你的身高
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
let height : CGFloat = 50 //Default cell Height
if likeLabel.text == nil || likeLabel.text == ""
height = height - likeLabelHeightConstraint.constant
likeLabelHeightConstraint.constant = 0
else
//Set default scenario
return height
如果您正在检索数据 asynchronously
,请确保在 DataSource 更新后重新加载数据....
【讨论】:
感谢您的回复。我的单元格已定义..DetailCell.swift。所以我试图在你的建议中声明,但我收到了“访问不正确”的消息。让 cell = tableView.dequeueReusableCellWithIdentifier("ShopDetailCell", forIndexPath: indexPath) as! ShopDetailCell 为您的表格视图类代码和自定义单元格类提供您遇到的实际错误 只有当我将 UILabel 更改为 KILabel 或 ActiveLabel 时才会发生这种情况。所以我认为这不是自动布局问题。但是有人知道这个问题吗?我该如何解决这个问题?以上是关于当 KILabel 或 ActiveLabel 没有字符串时,将其高度设置为 0。但原始 UILabel 工作正常的主要内容,如果未能解决你的问题,请参考以下文章