UITableview load cell longtime Swift - Need advise tuning - uitableview

Please kindly refer code in attach and refer in the image as well. I need your advise how can I make quicker for loading
http://imageshack.com/a/img901/7079/mOQkum.png
http://imageshack.com/a/img909/2775/E2zTKs.png
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell {
let wishRow = self.wishDataList.objectAtIndex(indexPath!.row) as! NSMutableArray
println(userImageList.count)
switch (wishRow).count{
case 4:
let cell:WishHeaderTableViewCell = tableView!.dequeueReusableCellWithIdentifier("CellHeader", forIndexPath: indexPath!) as! WishHeaderTableViewCell
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let dateFormatter = NSDateFormatter()
cell.LblCity.text = wishRow[1] as? String
cell.ImgAddWish.layer.cornerRadius = 20
cell.ImgAddWish.clipsToBounds = true
cell.ImgAddWish.autoresizesSubviews = false
// cell.ImageViewTripOwner.layer.cornerRadius = 20
// cell.ImageViewTripOwner.clipsToBounds = true
cell.ImageViewTripOwner.autoresizesSubviews = false
for object in self.userImageList{
if object[0] as? String == (wishRow[3] as? PFUser)?.objectId{
cell.ImageViewTripOwner.image = UIImage(data: (object[1] as! PFFile).getData()!)
//SharedFunction.imageResize(UIImage(data: (object[1] as PFFile).getData())!, sizeChange: CGSize(width: 40, height: 40))
}
}
})
return cell
default:
let cell:WishItemTableViewCell = tableView!.dequeueReusableCellWithIdentifier("CellItem", forIndexPath: indexPath!) as! WishItemTableViewCell
dispatch_async(dispatch_get_main_queue(), { () -> Void in
cell.LblItemName.text = wishRow[5] as? String
cell.ImgItem.image = wishRow[7] as? UIImage
//UIImage(data: (wishRow[7] as PFFile).getData())
//SharedFunction.imageResize(UIImage(data: (wishRow[7] as PFFile).getData())!, sizeChange: CGSize(width: 40, height: 40))
cell.ImgRequestorItem.layer.cornerRadius = 10
cell.ImgRequestorItem.clipsToBounds = true
cell.ImgRequestorItem.autoresizesSubviews = false
cell.ImgRequestorItem.backgroundColor = UIColor.whiteColor()
for object in self.userImageList{
if object[0] as? String == wishRow[8] as? String{
let realImage = UIImageView(frame: CGRect(x: 1.5, y: 1.5, width: 17, height: 17))
realImage.layer.cornerRadius = 8.5
realImage.clipsToBounds = true
dispatch_async(dispatch_get_main_queue(), { () -> Void in
realImage.image = UIImage(data: (object[1] as! PFFile).getData()!)
})
//SharedFunction.imageResize(UIImage(data: (object[1] as PFFile).getData())!, sizeChange: CGSize(width: 17, height: 17))
cell.ImgRequestorItem.addSubview(realImage)
}
}
cell.ImgBackgroundTick.layer.cornerRadius = 7.5
cell.ImgBackgroundTick.clipsToBounds = true
cell.ImgBackgroundTick.autoresizesSubviews = false
cell.ImgBackgroundTick.backgroundColor = UIColor.whiteColor()
let realImage = UIImageView(frame: CGRect(x: 1.5, y: 1.5, width: 12, height: 12))
realImage.layer.cornerRadius = 6
realImage.clipsToBounds = true
realImage.backgroundColor = UIColor(red: 0.450, green: 0.419, blue: 0.321 , alpha: 1)
realImage.image = UIImage(named: "ic_tick")
cell.ImgBackgroundTick.addSubview(realImage)
})
return cell
}
}

Wow, why are you using dispatch_async(dispatch_get_main_queue(), { () -> Void in in cell creation? You don't have to. Remove this method so the code should look like the following:
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell {
let wishRow = self.wishDataList.objectAtIndex(indexPath!.row) as! NSMutableArray
println(userImageList.count)
switch (wishRow).count{
case 4:
let cell = tableView!.dequeueReusableCellWithIdentifier("CellHeader", forIndexPath: indexPath!) as! WishHeaderTableViewCell
let dateFormatter = NSDateFormatter()
cell.LblCity.text = wishRow[1] as? String
cell.ImgAddWish.layer.cornerRadius = 20
cell.ImgAddWish.clipsToBounds = true
cell.ImgAddWish.autoresizesSubviews = false
// cell.ImageViewTripOwner.layer.cornerRadius = 20
// cell.ImageViewTripOwner.clipsToBounds = true
cell.ImageViewTripOwner.autoresizesSubviews = false
for object in self.userImageList{
if object[0] as? String == (wishRow[3] as? PFUser)?.objectId{
cell.ImageViewTripOwner.image = UIImage(data: (object[1] as! PFFile).getData()!)
//SharedFunction.imageResize(UIImage(data: (object[1] as PFFile).getData())!, sizeChange: CGSize(width: 40, height: 40))
}
}
return cell
default:
let cell = tableView!.dequeueReusableCellWithIdentifier("CellItem", forIndexPath: indexPath!) as! WishItemTableViewCell
cell.LblItemName.text = wishRow[5] as? String
cell.ImgItem.image = wishRow[7] as? UIImage
//UIImage(data: (wishRow[7] as PFFile).getData())
//SharedFunction.imageResize(UIImage(data: (wishRow[7] as PFFile).getData())!, sizeChange: CGSize(width: 40, height: 40))
cell.ImgRequestorItem.layer.cornerRadius = 10
cell.ImgRequestorItem.clipsToBounds = true
cell.ImgRequestorItem.autoresizesSubviews = false
cell.ImgRequestorItem.backgroundColor = UIColor.whiteColor()
for object in self.userImageList{
if object[0] as? String == wishRow[8] as? String{
let realImage = UIImageView(frame: CGRect(x: 1.5, y: 1.5, width: 17, height: 17))
realImage.layer.cornerRadius = 8.5
realImage.clipsToBounds = true
dispatch_async(dispatch_get_main_queue(), { () -> Void in
realImage.image = UIImage(data: (object[1] as! PFFile).getData()!)
})
//SharedFunction.imageResize(UIImage(data: (object[1] as PFFile).getData())!, sizeChange: CGSize(width: 17, height: 17))
cell.ImgRequestorItem.addSubview(realImage)
}
}
cell.ImgBackgroundTick.layer.cornerRadius = 7.5
cell.ImgBackgroundTick.clipsToBounds = true
cell.ImgBackgroundTick.autoresizesSubviews = false
cell.ImgBackgroundTick.backgroundColor = UIColor.whiteColor()
let realImage = UIImageView(frame: CGRect(x: 1.5, y: 1.5, width: 12, height: 12))
realImage.layer.cornerRadius = 6
realImage.clipsToBounds = true
realImage.backgroundColor = UIColor(red: 0.450, green: 0.419, blue: 0.321 , alpha: 1)
realImage.image = UIImage(named: "ic_tick")
cell.ImgBackgroundTick.addSubview(realImage)
return cell
}}

Related

UITapGestureRecognizer not working until I scroll all the way to the bottom

I have added a UITapGestureRecognizer to a label in a UITableViewCell, however the click only works after I scroll to the bottom of the table.
Once I scroll to the bottom the tap works perfectly and performs the segue, but until I do, it does not call the function.
I have verified that the if statement does evaluate as true before I scroll, so the recognizer is there, but it just doesn't work.
Any ideas as to why would be greatly appreciated.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
for viewToRemove in cell.subviews {
viewToRemove.removeFromSuperview();
}
let result = self.ResultArray[indexPath.row] as! NSDictionary;
let width = self.frame.width;
let rawTime = result["LogInDTM"] as? String;
let rawUNIT = result[“unit”] as? String;
let rawPersonID = result["PERS_ID"] as? String;
let rawName = result["PERS_NAME"] as? String;
let rawVehicle = result["Vehicle_ID"] as? String;
let rawCall = result["CALL_NO"] as? String;
var CleanVehicle = ""
if let tmpVehicle = rawVehicle {
CleanVehicle = tmpVehicle
}
var CleanCall = ""
if let tmpCall = rawCall {
CleanCall = tmpCall
}
var CleanUnit = ""
if let tmpUnit = rawUNIT {
CleanUnit = tmpUnit
}
//print(result);
let cellView = UIView(frame: CGRect(x: 0, y: 0, width: width, height: 30));
cellView.backgroundColor = .black;
cellView.layer.cornerRadius = 5;
cellView.layer.masksToBounds = true;
let UnitLabel = UILabel(frame: CGRect(x: 2, y: 0, width: width*0.15, height: 30));
UnitLabel.textColor = .white;
UnitLabel.layer.borderWidth = 1.0;
UnitLabel.layer.borderColor = self.configuration.SOOrange.cgColor;
UnitLabel.text = " "+CleanUnit;
UnitLabel.font = UIFont.systemFont(ofSize: 12, weight: UIFont.Weight(rawValue: 400));
UnitLabel.adjustsFontSizeToFitWidth = true;
cellView.addSubview(UnitLabel);
let SubjectLabel = UILabel(frame: CGRect(x: (width*0.15)+2, y: 0, width: width*0.4, height: 30));
SubjectLabel.textColor = .white;
SubjectLabel.layer.borderWidth = 1.0;
SubjectLabel.layer.borderColor = self.configuration.SOOrange.cgColor;
SubjectLabel.text = " "+rawName!;
SubjectLabel.font = UIFont.systemFont(ofSize: 12, weight: UIFont.Weight(rawValue: 400));
SubjectLabel.adjustsFontSizeToFitWidth = true;
cellView.addSubview(SubjectLabel);
let VehicleLabel = UILabel(frame: CGRect(x: (width*0.55)+2, y: 0, width: width*0.2, height: 30));
VehicleLabel.textColor = .white;
VehicleLabel.layer.borderWidth = 1.0;
VehicleLabel.layer.borderColor = self.configuration.SOOrange.cgColor;
VehicleLabel.text = " "+CleanVehicle;
VehicleLabel.font = UIFont.systemFont(ofSize: 12, weight: UIFont.Weight(rawValue: 400));
VehicleLabel.adjustsFontSizeToFitWidth = true;
cellView.addSubview(VehicleLabel);
let CallLabel = UILabel(frame: CGRect(x: (width*0.75)+2, y: 0, width: width*0.24, height: 30));
CallLabel.textColor = .white;
CallLabel.layer.borderWidth = 1.0;
CallLabel.layer.borderColor = self.configuration.SOOrange.cgColor;
CallLabel.text = " "+CleanCall;
CallLabel.font = UIFont.systemFont(ofSize: 12, weight: UIFont.Weight(rawValue: 400));
CallLabel.adjustsFontSizeToFitWidth = true;
if(CleanCall != ""){
print(CleanCall);
let callTap = UITapGestureRecognizer(target: self, action: #selector(self.openCall(_:)))
CallLabel.isUserInteractionEnabled = true
CallLabel.addGestureRecognizer(callTap)
}
cellView.addSubview(CallLabel);
cell.addSubview(cellView);
return cell;
}

Adding addChildViewController hangs the app

I am new in iOS.
I have a view controller in which I have added child view controller using addChildViewController in Parent Controller and it hangs the app.
addChildViewController has 2 webservice calling in the viewDidAppear method. It works fine when webservice calling complete. I want to know how to stop the app hangs problem when adding child view controller.
Below is the code how we add the child view controller:
self.stickerController = StickersViewController()
self.addChildViewController(self.stickerController)
self.addSubview(subView: self.stickerController.view, toView: self.view)
self.stickerController.view.isHidden = true
self.stickerController.didMove(toParentViewController: self)
StickersViewController view controller:
import Foundation
class StickersViewController: UIViewController,UICollectionViewDelegateFlowLayout, UICollectionViewDataSource,UISearchBarDelegate {
var yValue:CGFloat = 65
var navheight:CGFloat = 65
var searchView = UIView()
var searchField = UISearchBar()
let cellReuseIdentifier = "cell"
var tableView: UICollectionView!
var dataDictionary: NSMutableArray!
var imageCache = [String:UIImage]()
var titleHeight:CGFloat = 260
var pagenumber: String = "1"
var showAnimator: Bool = true
var isgetLastInsertId: Bool = false
var isRequestSend: Bool = false
var stopPagging : Bool = false
var callFromPagging: Bool = false
var noDataLabel = UILabel()
var tryAgainButton = UIButton()
var gallery_id:Int = 0
let cellReuseIdentifierEmoji = "cell"
var tableViewEmoji: UICollectionView!
var dataDictionaryEmoji: NSMutableArray!
var pagenumberEmoji: String = "1"
var isRequestSendEmoji: Bool = false
var stopPaggingEmoji : Bool = false
var noDataLabelEmoji = UILabel()
var callFromPaggingEmoji:Bool = false
var emojisCategory:UIScrollView!
var sepratorView:UIView!
var plusEmojiBtn = UILabel()
var userEmojiData:NSMutableArray!
var tabMenuHeight:CGFloat = 40
var isSearchBarHidden:Bool = false
var searchBarHeight:CGFloat = 40
var viewHeight:CGFloat = 0
var categoryTabMenuHeight:CGFloat = 0
override func viewDidLoad() {
if isSearchBarHidden == true{
yValue = 0
}else{
searchBarHeight = 80
}
if isSearchBarHidden == false{
viewHeight = self.view.frame.height
}
self.view.addSubview(searchView)
makeSearchView()
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
layout.itemSize = CGSize(width: view.frame.width, height: view.frame.height)
self.tableView = UICollectionView(frame:CGRect(x: 0, y: yValue , width: appWidth,height: viewHeight - yValue - searchBarHeight), collectionViewLayout: layout)
tableView.delegate = self
tableView.dataSource = self
tableView.register(EmoticonsCategoryTableViewCell.self, forCellWithReuseIdentifier: cellReuseIdentifier)
tableView.backgroundColor = appBackgroundColor
self.tableView.alwaysBounceVertical = true
self.tableView.alpha = 1
self.tableView.tag = 1
self.view.addSubview(tableView)
//emoji table
let layoutEmoji: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layoutEmoji.sectionInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
layoutEmoji.itemSize = CGSize(width: view.frame.width, height: view.frame.height)
self.tableViewEmoji = UICollectionView(frame:CGRect(x: 0, y: yValue , width: appWidth,height: viewHeight - yValue - tabMenuHeight - searchBarHeight - categoryTabMenuHeight), collectionViewLayout: layoutEmoji)
self.tableViewEmoji.tag = 2
tableViewEmoji.delegate = self
tableViewEmoji.dataSource = self
tableViewEmoji.register(ContentFeelingTableViewCell.self, forCellWithReuseIdentifier: cellReuseIdentifier)
tableViewEmoji.backgroundColor = appBackgroundColor
self.tableViewEmoji.alwaysBounceVertical = true
tableViewEmoji.alpha = 0
self.view.addSubview(tableViewEmoji)
showAnimator = true;
paramsPost.removeAll(keepingCapacity: false)
emojisCategory = UIScrollView(frame: CGRect(x: 0, y: viewHeight - searchBarHeight, width: appWidth - 40, height: 40))
view.addSubview(emojisCategory)
emojisCategory.backgroundColor = appBackgroundColor
sepratorView = UIView(frame: CGRect(x: 0, y: emojisCategory.frame.origin.y, width: appWidth , height: 1/divideSepratorScaleValue))
sepratorView.backgroundColor = appSepratorColor
view.addSubview(sepratorView)
plusEmojiBtn.frame = CGRect(x: emojisCategory.frame.width, y: emojisCategory.frame.origin.y + 1/divideSepratorScaleValue, width: 40, height: 40)
plusEmojiBtn.backgroundColor = appforgroundcolor
plusEmojiBtn.textColor = navigationColor
plusEmojiBtn.font = UIFont(name: fontIcon, size: fontSizeHuge)
plusEmojiBtn.text = "\u{f067}"
plusEmojiBtn.textAlignment = .center
view.addSubview(plusEmojiBtn)
plusEmojiBtn.isUserInteractionEnabled = true
let tabbedPlus = UITapGestureRecognizer(target: self, action: #selector(self.plusTabbed))
plusEmojiBtn.addGestureRecognizer(tabbedPlus)
}
#objc func plusTabbed() {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "EmojiStoreButtonClicked"), object: nil)
let pVc = EmojiStickerStore()
pVc.modalTransitionStyle = UIModalTransitionStyle.coverVertical
let navigationController = UINavigationController(rootViewController: pVc)
self.present(navigationController, animated: true, completion: nil)
}
func getData(){
let width = appWidth
let height = appHeight
if(showAnimator == true){
//show activity indicator
if(callFromPagging == false){
animator.center = self.tableView.center
}else{
animator.center = CGPoint(x: width/2, y: (height - CGFloat(activityIndicatorBottomHeight)))
}
animator.hidesWhenStopped = true
animator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
animator.startAnimating()
self.view.addSubview(animator)
}
if Reachability.isConnectedToNetwork() {
isRequestSend = true
noDataLabel.isHidden = true
tryAgainButton.isHidden = true
let imageData = Data()
paramsPost.removeAll(keepingCapacity: false)
//remove previous stored data
if !(searchField.text?.isEmpty)!{
paramsPost["search"] = searchField.text!
}
sendRequest(paramsPost as Dictionary<String, AnyObject>, url: "stickers/stickers/limit/"+limitCount+"/page/"+pagenumber, method: "POST",image:imageData) { (succeeded) -> () in
DispatchQueue.main.async(execute: {
if(self.pagenumber == "1" && self.dataDictionary != nil){
//remove all stored data from global variable
self.dataDictionary.removeAllObjects()
}
animator.stopAnimating()
if self.isgetLastInsertId == true
{
//stop refresh spinner
refreshControl.endRefreshing()
}
if(succeeded["error_message"] != nil){
if let code = succeeded["error_message"] as? String{
if !code.isEmpty{
openMaintainanceMode(view: self,code: code)
return
}
}
//alert error
self.view.makeToast(succeeded["error_message"]! as! String, duration: 5, position: .bottom)
}else{
//success
if let responseResult = succeeded["result"] as? NSDictionary{
//pagging data
// self.pagenumber = "\(responseResult["next_page"]!)"
//if(responseResult["total_page"] as! Int == responseResult["current_page"] /as! Int){
// self.stopPagging = true
//}else{
// self.stopPagging = false
// }
self.stopPagging = true
if(self.dataDictionary != nil && self.dataDictionary.count > 0){
for data in responseResult["emotions"] as! NSMutableArray {
self.dataDictionary.add(data as AnyObject)
}
}else{
// store in global variable
if(responseResult["emotions"] != nil){
self.dataDictionary = responseResult["emotions"] as! NSMutableArray
self.noDataLabel.isHidden = true
self.tryAgainButton.isHidden = true
//reload table view
self.tableView.reloadData()
}
}
}
self.tableView.reloadData()
}
if self.dataDictionary == nil || self.dataDictionary.count == 0{
self.noData()
}
//reinitialize default variables
self.isRequestSend = false
self.isgetLastInsertId = false
self.callFromPagging = false
})
}
}else{
self.view.makeToast(String(format: NSLocalizedString("No Internet Connection", comment: "")), duration: 5, position: .bottom)
}
}
func makeScrollEmojiContent() {
for i in 0..<userEmojiData.count{
if let dic = userEmojiData[i] as? NSDictionary{
let title = dic["title"] as! String
let id = dic["gallery_id"] as! Int
let label = UILabel(frame: CGRect(x: CGFloat(i*40), y: 0, width: 40, height: 40))
label.tag = id
if title == "search"{
label.font = UIFont(name: fontIcon, size: fontSizeHuge)
label.text = "\u{f002}"
label.textColor = navigationColor
label.backgroundColor = titleLightColor
}else{
let icon = dic["icon"] as! String
let attachment: NSTextAttachment = NSTextAttachment()
if let img = self.imageCache[icon]{
attachment.image = img
}else{
if let url = NSURL(string: icon) {
if let data = NSData.init(contentsOf: url as URL) {
let imageI = UIImage(data: data as Data)!
attachment.image = imageI
self.imageCache[icon] = imageI
}
}
}
attachment.bounds = CGRect(x: 0, y: -3, width: fontSizeHuge, height: fontSizeHuge)
let attachmentString: NSAttributedString = NSAttributedString(attachment: attachment)
label.attributedText = attachmentString
}
label.isUserInteractionEnabled = true
let tabbedPlus = UITapGestureRecognizer(target: self, action: #selector(self.labelTabbed(_:)))
label.addGestureRecognizer(tabbedPlus)
label.textAlignment = .center
emojisCategory.addSubview(label)
}
}
if userEmojiData != nil{
emojisCategory.contentSize = CGSize(width: CGFloat(userEmojiData.count * 40), height: emojisCategory.frame.height)
}
}
#objc func labelTabbed(_ sender:UITapGestureRecognizer) {
let viewS = sender.view as! UILabel
let tag = viewS.tag
for obj in emojisCategory.subviews{
if obj.tag != tag{
obj.backgroundColor = UIColor.clear
}else{
obj.backgroundColor = titleLightColor
}
}
self.searchField.text = ""
if tag == 0{
self.tableView.alpha = 1
self.searchView.alpha = 1
self.tableViewEmoji.alpha = 0
self.tableViewEmoji.frame.origin.y = yValue
self.noDataLabelEmoji.isHidden = true
self.tableViewEmoji.frame.size.height = viewHeight - yValue - tabMenuHeight - searchBarHeight
}else{
self.tableView.alpha = 0
self.searchView.alpha = 0
gallery_id = tag
self.tableViewEmoji.frame.origin.y = navheight
self.tableViewEmoji.frame.size.height = viewHeight - yValue - tabMenuHeight - categoryTabMenuHeight
if dataDictionaryEmoji != nil && dataDictionaryEmoji.count > 0{
dataDictionaryEmoji.removeAllObjects()
}
tableViewEmoji.reloadData()
getEmojiFeelingData()
}
}
func getEmojiFeelingData(){
self.tableView.alpha = 0
self.tableViewEmoji.alpha = 1
let width = appWidth
let height = appHeight
if(showAnimator == true){
//show activity indicator
if(callFromPagging == false){
animator.center = self.view.center
}else{
animator.center = CGPoint(x: width/2, y: (height - CGFloat(activityIndicatorBottomHeight)))
}
animator.hidesWhenStopped = true
animator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
animator.startAnimating()
self.view.addSubview(animator)
}
if Reachability.isConnectedToNetwork() {
isRequestSendEmoji = true
let imageData = Data()
paramsPost.removeAll(keepingCapacity: false)
//remove previous stored data
if !(searchField.text?.isEmpty)!{
paramsPost["search"] = searchField.text!
}
paramsPost["gallery_id"] = "\(self.gallery_id)"
sendRequest(paramsPost as Dictionary<String, AnyObject>, url: "stickers/emoji-content/", method: "POST",image:imageData) { (succeeded) -> () in
DispatchQueue.main.async(execute: {
if(self.pagenumberEmoji == "1" && self.dataDictionaryEmoji != nil){
//remove all stored data from global variable
self.dataDictionaryEmoji.removeAllObjects()
}
animator.stopAnimating()
if(succeeded["error_message"] != nil){
if let code = succeeded["error_message"] as? String{
if !code.isEmpty{
openMaintainanceMode(view: self,code: code)
return
}
}
//alert error
self.view.makeToast(succeeded["error_message"]! as! String, duration: 5, position: .bottom)
}else{
//success
if let responseResult = succeeded["result"] as? NSDictionary{
self.stopPaggingEmoji = true
if(self.dataDictionaryEmoji != nil && self.dataDictionaryEmoji.count > 0){
for data in responseResult["emotions"] as! NSMutableArray {
self.dataDictionaryEmoji.add(data as AnyObject)
}
}else{
// store in global variable
if(responseResult["emotions"] != nil){
self.dataDictionaryEmoji = responseResult["emotions"] as! NSMutableArray
self.noDataLabelEmoji.isHidden = true
//reload table view
self.tableViewEmoji.reloadData()
}
}
}
self.tableViewEmoji.reloadData()
}
if self.dataDictionaryEmoji == nil || self.dataDictionaryEmoji.count == 0{
self.noDataEmoji()
}
//reinitialize default variables
self.isRequestSendEmoji = false
self.callFromPaggingEmoji = false
})
}
}else{
self.view.makeToast(String(format: NSLocalizedString("No Internet Connection", comment: "")), duration: 5, position: .bottom)
}
}
func scrollViewDidScroll(_ sender:UIScrollView) {
view.endEditing(true)
}
func noDataEmoji() {
self.noDataLabelEmoji = UILabel(frame: CGRect( x: 0, y: 0, width: appWidth, height: 30))
self.noDataLabelEmoji.font = UIFont(name: fontName, size: fontSizeLarge)
self.view.backgroundColor = appBackgroundColor
self.noDataLabelEmoji.textFontColor()
self.noDataLabelEmoji.textAlignment = .center
self.noDataLabelEmoji.text = NSLocalizedString("No stickers to show.", comment: "")
self.noDataLabelEmoji.center = self.tableViewEmoji.center
self.view.addSubview(self.noDataLabelEmoji)
}
func noData() {
self.noDataLabel = UILabel(frame: CGRect( x: 0, y: 0, width: appWidth, height: 30))
self.noDataLabel.font = UIFont(name: fontName, size: fontSizeLarge)
self.view.backgroundColor = appBackgroundColor
self.noDataLabel.textAlignment = .center
self.noDataLabel.textColor = noDataLabelTextColor
self.noDataLabel.text = NSLocalizedString("No category found with the given search.", comment: "")
self.noDataLabel.center = self.tableView.center
self.view.addSubview(self.noDataLabel)
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView.tag == 2{
if(dataDictionaryEmoji != nil){
return dataDictionaryEmoji.count
}else{
return 0
}
}else{
if(dataDictionary != nil){
return dataDictionary.count
}else{
return 0
}
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
var width = appWidth - 20
if collectionView.tag == 1{
if (UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad)
{
// Ipad
width = (width - 5*2)/3
}
else
{
width = (width - 5*1)/2
}
return CGSize(width: width, height: 40)
}else{
if (UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad)
{
// Ipad
width = (width - 5*6)/6
}
else
{
width = (width - 5*4)/4
}
return CGSize(width: width, height: 60)
}
}
func makeSearchView() {
searchView.frame = CGRect(x: 0, y: yValue, width: appWidth, height: 50)
yValue = yValue + 50
searchField.frame = CGRect(x: 0, y: 0, width: appWidth, height: 50)
searchField.delegate = self
searchField.placeholder = NSLocalizedString("Search stickers", comment: "")
searchView.addSubview(searchField)
//change search text field attributes
for mainView in searchField.subviews {
for subView in mainView.subviews {
if let textField = subView as? UITextField {
textField.textColor = searchBarTextColor
textField.font = UIFont(name: fontName, size: fontSizeMedium)
}
}
}
}
func userEmojis() {
if Reachability.isConnectedToNetwork() {
let imageData = Data()
paramsPost.removeAll()
paramsPost["user_emojis"] = "1"
sendRequest(paramsPost as Dictionary<String, AnyObject>, url: "stickers/stickers/", method: "POST",image:imageData) { (succeeded) -> () in
DispatchQueue.main.async(execute: {
if(succeeded["error_message"] != nil){
if let code = succeeded["error_message"] as? String{
if !code.isEmpty{
openMaintainanceMode(view: self,code: code)
return
}
}
}else{
for obj in self.emojisCategory.subviews{
obj.removeFromSuperview()
}
//success
if let responseResult = succeeded["result"] as? NSDictionary{
if let userEmoji = responseResult["useremotions"] as? NSMutableArray{
self.emojisCategory.isHidden = false
self.sepratorView.isHidden = false
self.userEmojiData = userEmoji
self.makeScrollEmojiContent()
}else{
self.emojisCategory.isHidden = true
self.sepratorView.isHidden = true
}
}
}
})
}
}
}
override func viewDidAppear(_ animated: Bool) {
self.getData()
self.userEmojis()
}
func changeTableViewSize() {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "emojiSearchButtonTabbed"), object: nil)
}
}

UIScrollView Crashing after ReloadData

i have ScrollView in every row of tableView. i am assigning different tag to it.
it works perfectly for the first time. when change data in array and make ReloadData App Crashes.
Error is like
fatal error: unexpectedly found nil while unwrapping an Optional value
Piece of code
cell = tableView.dequeueReusableCell(withIdentifier: "ContentCell", for: indexPath)
let lblName = (cell.viewWithTag(31)! as! UILabel)
let lblSubmited = (cell.viewWithTag(32)! as! UILabel)
let lblFrom = (cell.viewWithTag(33)! as! UILabel)
let lblTo = (cell.viewWithTag(34)! as! UILabel)
let lblTotalHours = (cell.viewWithTag(35)! as! UILabel)
let lblapprove = (cell.viewWithTag(36)! as! UILabel)
lblName.text = dict.object(forKey: "name") as? String
lblSubmited.text = dict.object(forKey: "submitted") as? String
lblFrom.text = dict.object(forKey: "from") as? String
lblTo.text = dict.object(forKey: "to") as? String
lblTotalHours.text = dict.object(forKey: "tot") as? String
lblapprove.text = "Pending"
let scrollView:UIScrollView!
if(flag.object(at: indexPath.row) as! String == "0"){
scrollView = (cell.viewWithTag(3)! as! UIScrollView)
scrollView.tag = ((100 * indexPath.row)+1)
flag.replaceObject(at: indexPath.row, with: "1")
}
else{
scrollView = (cell.viewWithTag(((100 * indexPath.row)+1))! as! UIScrollView)
}
scrollView.delegate = self
scrollView.showsHorizontalScrollIndicator = false
let viewContent = (cell.viewWithTag(1000)!)
let btApprove = UIButton(frame: CGRect(x: 704.0, y: 10.0, width: 40.0, height: 40.0))
let btReject = UIButton(frame: CGRect(x: 788.0, y: 10.0, width: 40.0, height: 40.0))
let btDetail = UIButton(frame: CGRect(x: 860.0, y: 10.0, width: 40.0, height: 40.0))
btApprove.addTarget(self, action: #selector(self.approvePressedAction), for: .touchUpInside)
btReject.addTarget(self, action: #selector(self.rejectPressedAction), for: .touchUpInside)
btDetail.addTarget(self, action: #selector(self.detailPressedAction), for: .touchUpInside)
viewContent.addSubview(btApprove)
viewContent.addSubview(btReject)
viewContent.addSubview(btDetail)
return cell
error comes in
scrollView = (cell.viewWithTag(3)! as! UIScrollView)
line and crashes after reloadData. Any Solution?
Seems like you are forcing a lot of optionals to un-wrap, maybe check them first before trying to use them.
I have no idea what your logic is doing, but to run some checks on the specific line that crashes try something like this.
var scrollView:UIScrollView!
if(flag.object(at: indexPath.row) as! String == "0"){
if let view = cell.viewWithTag(3) {
if let sv = view as? UIScrollView {
scrollView = sv
scrollView.tag = ((100 * indexPath.row)+1)
flag.replaceObject(at: indexPath.row, with: "1")
} else {
print("view found with tag 3 but it's not a scrollview")
}
} else {
print("no view found with tag 3")
}
} else {
scrollView = (cell.viewWithTag(((100 * indexPath.row)+1))! as! UIScrollView)
}

Memory Usage with UICollectionView extremely high

I am having an issue with memory usage. Whenever I scroll or reload the data the memory usage keeps going up and never goes down. I have a feeling that for some reason the cells are not releasing any of the items displayed.
Any help would be greatly appreciated. I am quite sure I am doing something wrong, but I can't seem to find what.
Thank you in advance
Here is the code for creating my UICollectionView:
import Foundation
import UIKit
import CoreData
import Crashlytics
public class podCollectionView : UIViewController,UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout,UIPopoverPresentationControllerDelegate {
private var collectionView : UICollectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: UICollectionViewFlowLayout()) // Initialization
private var inmates : NSArray = [];
private var context : NSManagedObjectContext = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext;
private var configuration = Configuration.sharedInstance;
private var titleView = UILabel();
private var database : FMDatabase = (UIApplication.sharedApplication().delegate as! AppDelegate).database!;
public override func viewDidLoad() {
getInmates();
super.viewDidLoad();
self.collectionView = podMainView(x: "1", y: "2");
self.collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "CellCell") // UICollectionViewCell
self.collectionView.backgroundColor = UIColor.clearColor();
self.collectionView.layer.cornerRadius = 5;
self.collectionView.layer.masksToBounds = true;
self.collectionView.delegate = self // delegate : UICollectionViewDelegate
self.collectionView.dataSource = self // datasource : UICollectionViewDataSource
self.view.addSubview(self.collectionView);
self.view = self.collectionView;
self.navigationItem.setHidesBackButton(true, animated:false);
var inmateRefresh: NSTimer!
gameTimer = NSTimer.scheduledTimerWithTimeInterval(120, target: self, selector: #selector(refreshDAta), userInfo: nil, repeats: true);
}
public func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.inmates.count;
}
public func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let retVal : UICollectionViewCell = self.collectionView.dequeueReusableCellWithReuseIdentifier("CellCell", forIndexPath: indexPath);
retVal.prepareForReuse();
retVal.addSubview(InmateSummary(inmate: self.inmates.objectAtIndex(indexPath.item) as! NSArray,parent: self));
return retVal;
}
private func getInmates(){
var totalInmates = 0;
var inmatesInArea = 0;
var inmatesOutOfArea = 0;
self.inmates = [];
do{
let tmpInmates : NSMutableArray = [];
let rs = try self.database.executeQuery("SELECT * FROM inmates WHERE podName='"+self.configuration.currentArea+"' ORDER BY suicideBlue DESC", values: nil)
while rs.next() {
let rowData : NSMutableArray = []
let colCount = Int(rs.columnCount()) as Int;
for i in 0 ..< colCount {
rowData.addObject(rs.objectForColumnName(rs.columnNameForIndex(Int32(i))));
}
if rowData[7] as! String == "" {
inmatesInArea = inmatesInArea + 1;
}else{
inmatesOutOfArea = inmatesOutOfArea + 1;
}
totalInmates = totalInmates + 1;
tmpInmates.addObject(rowData);
}
self.inmates = tmpInmates;
} catch {
CLSLogv("Error while loading inmates in main screen \(error)%#", getVaList(["three"]));
}
let barText = String(inmatesInArea) + "/" + String(inmatesOutOfArea) + " (" + String(totalInmates) + ")";
let buttonBack: UIButton = UIButton(type: UIButtonType.Custom) as UIButton
buttonBack.frame = CGRectMake(0, 0, 100, 40)
buttonBack.setTitle(barText, forState: .Normal);
let leftBarButtonItem: UIBarButtonItem = UIBarButtonItem(customView: buttonBack)
self.navigationItem.setLeftBarButtonItem(leftBarButtonItem, animated: false)
//self.database.close();
}
public func changePod(pod:String){
self.configuration.currentArea = pod;
self.titleView.text = pod + " ▼";
self.getInmates();
self.collectionView.reloadData();
}
public func refreshDAta(){
self.database.close();
self.database.open();
let inmateFetcer = InmateFetcher();
inmateFetcer.getUpdates();
self.getInmates();
//self.inmates = [];
self.collectionView.reloadData();
NSLog("DATA REFRESHED");
}
override public func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
}
And here is the code for the views within the cells:
import Foundation
import UIKit
public class InmateSummary : UIView, UIPopoverPresentationControllerDelegate{
public var inmate:NSArray;
private var screenSize : CGRect = UIScreen.mainScreen().bounds;
private var configuration = Configuration.sharedInstance;
private var parent : podCollectionView;
init(inmate:NSArray, parent:podCollectionView){
let cellHeight = screenSize.height * 0.295;
let cellWidth = screenSize.width * 0.295;
self.inmate = inmate;
self.parent = parent;
super.init(frame: CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight));
let aSelector : Selector = #selector(InmateSummary.inmateClicked(_:));
let tapGesture = UITapGestureRecognizer(target: self, action: aSelector);
tapGesture.numberOfTapsRequired = 1;
self.addGestureRecognizer(tapGesture);
self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1);
let topView = UIView(frame: CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight*0.10));
topView.backgroundColor = UIColor.grayColor();
self.addSubview(topView);
let cellLab = UILabel(frame: CGRect(x: 0, y: 0, width: cellWidth, height: cellHeight*0.10));
cellLab.text = self.inmate[3] as? String;
cellLab.textColor = UIColor.whiteColor();
cellLab.font = UIFont.init(name:"Arial-BoldMT", size: 30);
cellLab.textAlignment = NSTextAlignment.Center;
self.addSubview(cellLab);
let sexLab = UILabel(frame: CGRect(x: cellWidth*0.75, y: 0, width: cellWidth*0.25, height: cellHeight*0.10));
sexLab.text = self.inmate[1] as? String
sexLab.textColor = UIColor.whiteColor();
sexLab.textAlignment = NSTextAlignment.Center;
self.addSubview(sexLab);
let greyView = UIView(frame: CGRect(x: 0, y: cellHeight*0.10, width: cellWidth, height: cellHeight*0.70));
greyView.backgroundColor = UIColor.grayColor();
self.addSubview(greyView);
if self.inmate[7] as? String == "" {
greyView.backgroundColor = UIColor.blackColor();
}
let eventLab = UILabel(frame: CGRect(x: cellWidth*0.75, y: 0, width: cellWidth*0.25, height: cellHeight*0.10));
eventLab.text = self.inmate[7] as? String;
eventLab.textColor = UIColor.whiteColor();
eventLab.textAlignment = NSTextAlignment.Center;
eventLab.adjustsFontSizeToFitWidth = true;
greyView.addSubview(eventLab);
let classLab = UILabel(frame: CGRect(x: 0, y: 0, width: cellWidth*0.25, height: cellHeight*0.10));
classLab.text = self.inmate[4] as? String;
classLab.textAlignment = NSTextAlignment.Center;
classLab.font = UIFont.init(name:"Arial-BoldMT", size: 20);
classLab.adjustsFontSizeToFitWidth = true;
if(classLab.text == "RISK"){
classLab.textColor = UIColor.yellowColor();
}else if(classLab.text == "7CLS"){
classLab.textColor = UIColor(red: 1.0, green:0.5, blue:0.0, alpha:1);
}else if(classLab.text == "8MAX"){
classLab.textColor = UIColor(red:1.0, green:0.0, blue:0.0, alpha:0.7);
}else{
classLab.textColor = UIColor.whiteColor();
}
greyView.addSubview(classLab);
var mugshot : UIImage = UIImage();
if (self.inmate[12] as? NSData) != nil {
mugshot = UIImage(data: (self.inmate[12] as? NSData)!)!;
}else{
NSLog("Inmate without mugshot: %#",self.inmate[2] as! String);
}
let mugshotView = UIImageView(frame: CGRect(x: cellWidth*0.16, y: cellHeight*0.09, width: cellWidth*0.66, height: cellHeight*0.5));
mugshotView.image = mugshot;
greyView.addSubview(mugshotView);
let bookingNumber = UILabel(frame: CGRect(x: cellWidth*0.25, y: cellHeight*0.545, width: cellWidth*0.50, height: cellHeight*0.15));
bookingNumber.text = self.inmate[2] as? String;
bookingNumber.textColor = UIColor.whiteColor();
bookingNumber.textAlignment = NSTextAlignment.Center;
bookingNumber.font = UIFont.init(name:"Arial-BoldMT", size: 20);
bookingNumber.adjustsFontSizeToFitWidth = true;
greyView.addSubview(bookingNumber);
let nameView = UIView(frame: CGRect(x: 0, y: cellHeight*0.75, width: cellWidth, height: cellHeight*0.25));
self.addSubview(nameView);
let maxRed = UIView(frame: CGRect(x: 0, y: 0, width: cellWidth*0.33, height: cellHeight*0.115));
maxRed.backgroundColor = UIColor.blackColor();
if (self.inmate[15] as! NSNumber == 1) {
maxRed.backgroundColor = UIColor.redColor();
}
nameView.addSubview(maxRed);
let suBlue = UIView(frame: CGRect(x: cellWidth*0.33, y: 0, width: cellWidth*0.33, height: cellHeight*0.115));
suBlue.backgroundColor = UIColor.blackColor();
if (self.inmate[18] as! NSNumber == 1) {
let aSelector : Selector = #selector(InmateSummary.suicideClicked(_:));
let tapGesture = UITapGestureRecognizer(target: self, action: aSelector);
tapGesture.numberOfTapsRequired = 1;
nameView.addGestureRecognizer(tapGesture);
suBlue.backgroundColor = UIColor.blueColor();
}
nameView.addSubview(suBlue);
let segGreen = UIView(frame: CGRect(x: cellWidth*0.66, y: 0, width: cellWidth*0.33, height: cellHeight*0.115));
segGreen.backgroundColor = UIColor.blackColor();
if (self.inmate[5] as! NSNumber == 1) {
segGreen.backgroundColor = UIColor.greenColor();
}
nameView.addSubview(segGreen);
let nameLab = UILabel(frame: CGRect(x: cellWidth*0.025, y: cellHeight*0.12, width: cellWidth*0.95, height: cellHeight*0.05));
nameLab.text = self.inmate[0] as? String;
nameLab.textAlignment = NSTextAlignment.Center;
nameLab.textColor = UIColor.whiteColor();
nameLab.font = UIFont.init(name:"Arial-BoldMT", size: 20);
nameLab.adjustsFontSizeToFitWidth = true;
nameView.addSubview(nameLab);
if(self.inmate[18] as! NSNumber == 1){
//NSLog("Suicide: %#",self.inmate);
let checkLab = UILabel(frame: CGRect(x: 0, y: cellHeight*0.17, width: cellWidth, height: cellHeight*0.07));
let formatter = NSDateFormatter()
formatter.dateFormat = "MM/dd HH:mm"
let tmpDate = NSDate(timeIntervalSince1970: (self.inmate[19] as! NSString).doubleValue)
let dateString = formatter.stringFromDate(tmpDate);
checkLab.text = (self.inmate[22] as? String)! + " - " + dateString;
checkLab.textAlignment = NSTextAlignment.Center;
checkLab.textColor = UIColor.whiteColor();
checkLab.font = UIFont.init(name:"Arial", size: 18);
checkLab.adjustsFontSizeToFitWidth = true;
nameView.addSubview(checkLab);
}
if self.inmate[1] as? String == "F" {
nameView.backgroundColor = UIColor.purpleColor();
}
self.layer.cornerRadius = 5;
self.layer.borderColor = UIColor.grayColor().CGColor;
self.layer.borderWidth = 1;
self.layer.masksToBounds = true;
}
func suicideClicked(sender:UITapGestureRecognizer!){
let podsChooser = ActivityChooser(parentView:self);
podsChooser.modalPresentationStyle = .Popover;
let popoverMenuViewController = podsChooser.popoverPresentationController
popoverMenuViewController!.permittedArrowDirections = .Any
popoverMenuViewController!.delegate = self
popoverMenuViewController!.sourceView = sender.view;
self.parent.presentViewController(
podsChooser,
animated: true,
completion: nil)
}
func inmateClicked (sender:InmateSummary){
NSLog("Inmate Clicked");
let vc = SingleInmateDisplay(inmate: inmate);
self.parent.navigationController!.pushViewController(vc,animated:false);
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

UICollectionViewCell UIImage Lag even with dispatch_async

Symptom lag appears upon rendering a cell in collection view cell, I've recorded it here https://youtu.be/2utKOpHMshs
I'm not quite sure how the lag is happening and starting to suspect it has something to do with the recipe name element else rather than the UIImage since it's on another thread.
Async function
func asyncLoadImage(data: NSData, imageView: UIImageView) {
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
var image: UIImage!
NSLog("loading image")
image = UIImage(data: data)
dispatch_async(dispatch_get_main_queue()) {
imageView.image = image
NSLog("render image")
}
}
}
RecipeListViewController
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(Storyboard.CellIdentifier, forIndexPath: indexPath) as!RecipeListCollectionViewCell
let recipe = recipes[indexPath.item] as! Recipe
cell.recipeName?.text = recipe.name?.uppercaseString
cell.layer.shouldRasterize = true
cell.layer.rasterizationScale = UIScreen.mainScreen().scale
if (recipe.photo != nil) {
asyncLoadImage(recipe.photo!, imageView: cell.recipeImageView)
}
return cell
}
UICollectionViewCell:init
recipeImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height-100))
recipeImageView.contentMode = UIViewContentMode.ScaleAspectFill
recipeImageView.clipsToBounds = true
self.addSubview(recipeImageView)
recipeName = UILabel(frame: CGRect(x: 0, y: frame.size.height-100, width: frame.size.width, height: 50))
recipeName.backgroundColor = UIColor(red: 255, green: 255, blue: 255, alpha: 1)
recipeName.textColor = UIColor.blackColor()
recipeName.textAlignment = NSTextAlignment.Center
recipeName.font = UIFont.boldSystemFontOfSize(18.00)
self.addSubview(recipeName)
The issue resolved by removing the following code
cell.layer.shouldRasterize = true
cell.layer.rasterizationScale = UIScreen.mainScreen().scale

Resources