我是iOS的新手。
我有一个视图控制器,我在父控制器中使用addChildViewController添加了子视图控制器,它挂起了应用程序。
addChildViewController在viewDidAppear方法中有2个webservice调用。当webservice调用完成时,它工作正常。我想知道如何在添加子视图控制器时停止应用程序挂起问题。
下面是我们添加子视图控制器的代码:
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视图控制器:
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)
}
}