I am working on an app in which i am using UITableviewCell to display feed data. In Cell i am using multiple UIButtons to perform actions.
The main issue arise when i perform action through buttons the method is not called for the very first time(TableViewCell content is not updated). But when i press button second time it works fine.
Here is my code
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell_Reels", for: indexPath) as! Cell_Reels
cell.delegate = self
DispatchQueue.main.asyncAfter(deadline: .now()+0.1) { [self] in
UIView.animate(withDuration: 12.0, delay: 1, options: ([.curveLinear, .repeat]), animations: {() -> Void in
cell.marqueeLabel.center = CGPoint.init(x: 35 - cell.marqueeLabel.bounds.size.width / 2, y: cell.marqueeLabel.center.y)
}, completion: { _ in })
cell.likebutton.tag = indexPath.row
cell.FollowButton.tag = indexPath.row
cell.shareBtn.tag = indexPath.row
cell.shareBtn.addTarget(self, action: #selector(buttonShare), for: .touchUpInside)
let VideoStr = self.videos[indexPath.row]["media"].string ?? ""
self.fullVideoUrl = "\(KeyConstant.KBaseImageURL)\(VideoStr)"
//print("======", self.fullVideoUrl)
cell.configureCell( videoUrl: self.fullVideoUrl)
self.pausePlayeVideos()
cell.totalViews.text = "\(self.videos[indexPath.row]["count_view"].string ?? "") Views"
cell.nameLbl.text = self.videos[indexPath.row]["full_name"].string ?? ""
cell.descLbl.text = self.videos[indexPath.row]["title"].string ?? ""
cell.marqueeLabel.text = self.videos[indexPath.row]["title"].string ?? ""
cell.idLbl.text = self.videos[indexPath.row]["id"].string ?? ""
cell.likedLbl.text = self.videos[indexPath.row]["like_status"].string ?? ""
cell.followedLbl.text = self.videos[indexPath.row]["follow_status"].string ?? ""
self.currentLikesStr = self.videos[indexPath.row]["count_like"].string ?? ""
cell.likesCountLabel.text = "\(self.currentLikesStr) Likes"
self.followedStr = self.videos[indexPath.row]["follow_status"].string ?? ""
print("followedStr ppppppppppppppppppppppppp",followedStr, cell.idLbl.text!)
if self.followedStr == "0"
{
cell.FollowButton .setTitle("Follow", for: UIControl.State.normal)
}
else
{
cell.FollowButton .setTitle("Following", for: UIControl.State.normal)
}
self.likedStr = self.videos[indexPath.row]["like_status"].string ?? ""
print("likedStr -=-==-===-=-=-",likedStr, cell.idLbl.text!)
if likedStr == "0"
{
let selectedImage = UIImage(named: "heart_y2_30x30") as UIImage?
cell.likebutton.setImage(selectedImage, for: UIControl.State.normal)
}
else
{
let selectedImage = UIImage(named: "heart_y_30x30") as UIImage?
cell.likebutton.setImage(selectedImage, for: UIControl.State.normal)
}
cell.CommentsCountLabel.text = "Comments"
}
return cell
}
Button method decleration
func addFollowed(cell: Cell_Reels)
{
followedStr = cell.followedLbl.text!
let idstr = cell.idLbl.text
print(userId, idstr ?? "", followedStr)
let VideoidStr = cell.idLbl.text
print("=====", VideoidStr!)
let deviceid = "12345"
//print(videoId)
WebServiceHelper.sharedInstanceAPI.hitPostAPI(urlString: KeyConstant.APIFollow, params: ["user_id":userId, "device_id": deviceid, "device_type" : "iOS", "video_id":VideoidStr!], completionHandler: { (result: [String:Any], err:Error?) in
//print(result)
DispatchQueue.main.async {
//MBProgress().hideIndicator(view: self.view)
}
if(!(err == nil))
{
return
}
let json = JSON(result)
let statusCode = json["status"].string
//print(json)
if(statusCode == "success")
{
DispatchQueue.main.asyncAfter(deadline: .now()+0.1) { [self] in
self.followedStr = json["follow_status"].string ?? ""
cell.followedLbl.text = "\(self.followedStr)"
print(self.followedStr)
print(";;;;;;;;;;;;;;;;;;", self.followedStr)
if self.followedStr == "0"
{
cell.FollowButton .setTitle("Follow", for: UIControl.State.normal)
self.followedStr = "1"
self.arrayTempData[cell.FollowButton.tag] = 1
}
else
{
cell.FollowButton .setTitle("Following", for: UIControl.State.normal)
self.followedStr = "0"
self.arrayTempData[cell.FollowButton.tag] = 0
}
}
}
})
self.tblInstaReels.reloadData()
self.followedStr = ""
}
This i defined in TableViewCell class
protocol TableViewCellDelegate
{
func addTapped(cell: Cell_Reels, Tlikes : String)
func addFollowed(cell: Cell_Reels)
}
class Cell_Reels: UITableViewCell, ASAutoPlayVideoLayerContainer
{
var delegate: TableViewCellDelegate?
#IBOutlet weak var likedLbl : UILabel!
#IBOutlet weak var followedLbl : UILabel!
#IBOutlet weak var idLbl : UILabel!
#IBOutlet weak var nameLbl : UILabel!
#IBOutlet weak var likesCountLabel : UILabel!
#IBOutlet weak var CommentsCountLabel : UILabel!
#IBOutlet weak var marqueeLabel: UILabel!
#IBOutlet weak var imgReels: UIImageView!
#IBOutlet weak var Bkview: UIView!
#IBOutlet weak var PauseBtn: UIButton!
#IBOutlet weak var descLbl: UILabel!
#IBOutlet weak var shareBtn : UIButton!
#IBOutlet weak var likebutton : UIButton!
#IBOutlet weak var FollowButton : UIButton!
#IBOutlet weak var totalViews : UILabel!
var playerController: ASVideoPlayerController?
var videoLayer: AVPlayerLayer = AVPlayerLayer()
var likestr = ""
private(set) var liked = false
private(set) var followed = false
var VideoId = ""
#IBAction func followed(_ sender: Any)
{
delegate?.addFollowed(cell: self)
}
#IBAction func like(_ sender: Any)
{
delegate?.addTapped(cell: self, Tlikes: self.likedLbl.text!)
}
func likeVideo()
{
print("==========", likestr)
}
var videoURL: String?
{
didSet {
if let videoURL = videoURL
{
ASVideoPlayerController.sharedVideoPlayer.setupVideoFor(url: videoURL)
}
videoLayer.isHidden = videoURL == nil
}
}
override func awakeFromNib()
{
super.awakeFromNib()
imgReels.layer.addSublayer(videoLayer)
selectionStyle = .none
}
func configureCell(videoUrl: String?)
{
self.videoURL = videoUrl
}
override func prepareForReuse()
{
imgReels.imageURL = nil
super.prepareForReuse()
}
override func layoutSubviews()
{
super.layoutSubviews()
let horizontalMargin: CGFloat = 20
let width: CGFloat = bounds.size.width - horizontalMargin * 2
let height: CGFloat = (width * 0.9).rounded(.up)
videoLayer.frame = CGRect(x: 0, y: 0, width: imgReels.layer.frame.width, height: imgReels.layer.frame.height)
}
func visibleVideoHeight() -> CGFloat
{
return imgReels.frame.size.height
let videoFrameInParentSuperView: CGRect? = self.superview?.superview?.convert(imgReels.frame, from: imgReels)
guard let videoFrame = videoFrameInParentSuperView,
let superViewFrame = imgReels?.frame else {
return 0
}
let visibleVideoFrame = videoFrame.intersection(superViewFrame)
return visibleVideoFrame.size.height
}
}
in place of calling a separate method, use the addTarget method.
if you update anything in table view then perform all operations in cellForRowAt else after scrolling it reused the cell and it will create ambiguity
reload the table view in the main thread.
Related
Hi everyOne actually I want to add Data of the cell in tableView that when I click on it , data should pass on showOfferController(another view controller) but I dont why my data is nil when passed on showOfferController:
this is my prepareForSegue function :
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "cellToShow" {
let prePag = segue.destination as! ShowOfferController
//print("title : \(title)")
if WelcomeJson.CodingKeys.title.rawValue == titleItem {
prePag.celanderItem = WelcomeJson.CodingKeys.dateOfExpire.rawValue
prePag.itemImage[0] = imageString
prePag.itemAddress = WelcomeJson.CodingKeys.address.rawValue
prePag.itemOffer = WelcomeJson.CodingKeys.offer.rawValue
prePag.itemDefine = WelcomeJson.CodingKeys.about.rawValue
}
}
}
And also this is my DidSelectRow TableView function :
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "cellToShow", sender: nil)
}
this is my ShowOfferController on main.storyBoard and also my viewController or VC1 that tabelViewCell point to ShowOfferController:
And here my ShowOfferController.swift code :
class ShowOfferController: UIViewController, UIScrollViewDelegate {
#IBOutlet weak var offerScroll: UIScrollView!
#IBOutlet weak var offerPageController: UIPageControl!
#IBOutlet weak var getLabel: UILabel!
#IBOutlet weak var percentLbl: UILabel!
#IBOutlet weak var calendar: UILabel!
#IBOutlet weak var address: UILabel!
let locations = NSTextAttachment()
let calendars = NSTextAttachment()
let precents = NSTextAttachment()
var itemAddress : String = ""
var itemOffer : String = ""
var celanderItem : String = ""
var itemImage : [String] = []
var itemDefine : String = ""
var frame: CGRect = CGRect(x:0, y:0, width:0, height:0)
override func viewDidLoad() {
super.viewDidLoad()
print("item of images is : \(itemImage)")
// Do any additional setup after loading the view.
offerPageController.numberOfPages = itemImage.count
setupImages()
offerScroll.delegate = self
getLabel.text = itemDefine
locations.image = UIImage(systemName: "location.fill")
let locationVaAdress = NSMutableAttributedString(string: ". ")
locationVaAdress.append(NSAttributedString(attachment: locations))
locationVaAdress.append(NSAttributedString(string: " \(itemAddress)"))
address.attributedText = locationVaAdress
calendars.image = UIImage(systemName: "calendar")
let calendarss = NSMutableAttributedString(string: ". ")
calendarss.append(NSAttributedString(attachment: calendars))
calendarss.append(NSAttributedString(string: " \(celanderItem)"))
calendar.attributedText = calendarss
precents.image = UIImage(systemName: "percent")
let percentAndDarsad = NSMutableAttributedString(string: ". ")
percentAndDarsad.append(NSAttributedString(attachment: precents))
percentAndDarsad.append(NSAttributedString(string: " \(itemOffer)"))
percentLbl.attributedText = percentAndDarsad
}
func setupImages() {
for index in 0..<itemImage.count {
// 1.
frame.origin.x = offerScroll.frame.size.width * CGFloat(index)
frame.size = offerScroll.frame.size
let correctScope = itemImage[index].addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)
let unoptionalScope = correctScope!
let imgUrl = URL(string: "http://5.63.13.16:8080/\(unoptionalScope)")!
if let data = try? Data(contentsOf: imgUrl) {
let imgOffer = UIImageView(frame: frame)
imgOffer.image = UIImage(data: data)
self.offerScroll.addSubview(imgOffer)
}
offerScroll.contentSize = CGSize(width: (offerScroll.frame.size.width * CGFloat(itemImage.count)), height: offerScroll.frame.size.height)
offerScroll.delegate = self
}
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageNumber = offerScroll.contentOffset.x / offerScroll.frame.size.width
offerPageController.currentPage = Int(pageNumber)
}
so what's your idea ?
You should make (drag) the segue from on top of the table view controller in the storyboard instead of from the row
I try to pass imageName string data from ViewController to ImageViewController
which also func sliderImageTapped is sending data to CPImageSlider class
// ViewController.swift
import UIKit
let _AUTO_SCROLL_ENABLED : Bool = false
class ViewController: UIViewController, CPSliderDelegate {
var imagesArray = [String]()
var passDataDelegate: PassImageName?
#IBOutlet weak var slider : CPImageSlider!
#IBOutlet weak var autoSwitch : UISwitch!
#IBOutlet weak var arrowSwitch : UISwitch!
#IBOutlet weak var indicatorSwitch : UISwitch!
#IBOutlet weak var sliderSwitch : UISwitch!
#IBOutlet weak var circularSwitch : UISwitch!
override func viewDidLoad() {
super.viewDidLoad()
imagesArray = ["wallpaper1.jpg","wallpaper2.jpg","wallpaper3.jpg","wallpaper4.jpg"]
slider.images = imagesArray
slider.delegate = self
let zoom : CGFloat = 0.8
autoSwitch.transform = CGAffineTransform(scaleX: zoom, y: zoom)
arrowSwitch.transform = CGAffineTransform(scaleX: zoom, y: zoom)
indicatorSwitch.transform = CGAffineTransform(scaleX: zoom, y: zoom)
sliderSwitch.transform = CGAffineTransform(scaleX: zoom, y: zoom)
circularSwitch.transform = CGAffineTransform(scaleX: zoom, y: zoom)
autoSwitch.isOn = slider.autoSrcollEnabled
arrowSwitch.isOn = slider.enableArrowIndicator
indicatorSwitch.isOn = slider.enablePageIndicator
sliderSwitch.isOn = slider.enableSwipe
circularSwitch.isOn = slider.allowCircular
}
func sliderImageTapped(slider: CPImageSlider, imageName: String, index: Int) {
passDataDelegate?.passData(clickedImageName: imageName)
guard let destinationVC = storyboard?.instantiateViewController(withIdentifier: "ImageViewController") as? ImageViewController else {
return
}
present(destinationVC, animated: true, completion: nil )
print("\(index)")
}
}
// ImageViewController.swift
import UIKit
protocol PassImageName {
func passData(clickedImageName:String)
}
class ImageViewController: UIViewController, PassImageName {
#IBOutlet weak var image: UIImageView!
var imageName:String?
func passData(clickedImageName: String) {
imageName = clickedImageName
}
override func viewDidLoad() {
super.viewDidLoad()
image.image = UIImage(named: imageName ?? "wallpaper1.jpg")
}
#IBAction func dismiss(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
}
You must initialize passDataDelegate before call the delegate method.
func sliderImageTapped(slider: CPImageSlider, imageName: String, index: Int) {
guard let destinationVC = storyboard?.instantiateViewController(withIdentifier: "ImageViewController") as? ImageViewController else {
return
}
passDataDelegate = destinationVC
passDataDelegate?.passData(clickedImageName: imageName)
present(destinationVC, animated: true, completion: nil )
print("\(index)")
}
I don't understand the point of your delegate, is there something preventing you to just set the imageName after instantiating the ImageViewController ?
func sliderImageTapped(slider: CPImageSlider, imageName: String, index: Int) {
guard let destinationVC = storyboard?.instantiateViewController(withIdentifier: "ImageViewController") as? ImageViewController else {
return
}
destinationVC.imageName = imageName
present(destinationVC, animated: true, completion: nil )
print("\(index)")
}
And then just set your image inside it :
var imageName:String? {
didSet {
image.image = UIImage(named: imageName ?? "wallpaper1.jpg")
}
}
Hi I'm a new swift developer and I'm trying to find a way to load all of my textfields in the background thread then make it go back to the mainthread before a viewcontroller appear.
Because in my viewcontroller I have like almost 20 textfield that need to setup like its style, placeholders and etc.. So it takes quite a while for the viewcontroller to appear when I tapped on the button that handle segue to that vc.
I know that I can use this to do the setup textfields in the background
DispatchQueue.global(qos: .userInteractive).async {
<#code#>
}
however I dont know where to put this code. I tried to put it in the viewDidLoad but that doesnt seem to work.
EDIT: ADD IN MY CODE
import UIKit
import MaterialComponents.MaterialTextFields
class AddNewDataVC: UIViewController {
//Outlet
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var saveNewDataBtn: UIButton!
#IBOutlet weak var sowInfoInputsStackView: UIStackView!
#IBOutlet weak var giltInfoInputsStackView: UIStackView!
#IBOutlet weak var matingInfoInputsStackView: UIStackView!
#IBOutlet weak var farrowInfoInputsStackView: UIStackView!
#IBOutlet weak var vaccinTable: UITableView!
#IBOutlet weak var pigTypeTextField: PickerTextField!
#IBOutlet weak var genderTextField: PickerTextField!
#IBOutlet weak var chipIDTextField: MDCTextField!
#IBOutlet weak var breedTextField: MDCTextField!
#IBOutlet weak var subBreedTextField: MDCTextField!
#IBOutlet weak var dadIDTextField: MDCTextField!
#IBOutlet weak var momIDTextField: MDCTextField!
#IBOutlet weak var penIDTextField: MDCTextField!
#IBOutlet weak var weightTextField: MDCTextField!
#IBOutlet weak var parityTextField: MDCTextField!
#IBOutlet weak var birthDateTextField: PickerTextField!
#IBOutlet weak var weanDateTextField: PickerTextField!
#IBOutlet weak var arrivalDateTextField: PickerTextField!
#IBOutlet weak var herdEntryDateTextField: PickerTextField!
#IBOutlet weak var startOffDutySowDateTextField: PickerTextField!
#IBOutlet weak var semenFromBoarIDTextField: MDCTextField!
#IBOutlet weak var technicianNameTextField: PickerTextField!
#IBOutlet weak var matingDateTextField: PickerTextField!
#IBOutlet weak var estimateBirthDateTextField: PickerTextField!
#IBOutlet weak var realBirthDateTextField: PickerTextField!
#IBOutlet weak var totalNumberOfNewBornsTextField: MDCTextField!
#IBOutlet weak var totalNumberOfDeadNewBornsTextField: MDCTextField!
#IBOutlet weak var averageWeightOfNewBornsTextField: MDCTextField!
#IBOutlet weak var accoucheurNameTextField: MDCTextField!
#IBOutlet weak var newBornDeathReason1TextField: MDCTextField!
#IBOutlet weak var newBornDeathReason2TextField: MDCTextField!
#IBOutlet weak var newBornDeathReason3TextField: MDCTextField!
#IBOutlet weak var newBornCullReason1TextField: MDCTextField!
#IBOutlet weak var newBornCullReason2TextField: MDCTextField!
#IBOutlet weak var newBornCullReason3TextField: MDCTextField!
//Properties
var pigTypeController: MDCTextInputControllerUnderline?
var genderController: MDCTextInputControllerUnderline?
var chipIDController: MDCTextInputControllerUnderline?
var breedController: MDCTextInputControllerUnderline?
var subBreedController: MDCTextInputControllerUnderline?
var dadIDController: MDCTextInputControllerUnderline?
var momIDController: MDCTextInputControllerUnderline?
var penIDController: MDCTextInputControllerUnderline?
var weightController: MDCTextInputControllerUnderline?
var parityController: MDCTextInputControllerUnderline?
var birthDateController: MDCTextInputControllerUnderline?
var weanDateController: MDCTextInputControllerUnderline?
var arrivalDateController: MDCTextInputControllerUnderline?
var herdEntryDateController: MDCTextInputControllerUnderline?
var startOffDutySowDateController: MDCTextInputControllerUnderline?
var semenFromBoarIDController: MDCTextInputControllerUnderline?
var techicianNameController: MDCTextInputControllerUnderline?
var matingDateController: MDCTextInputControllerUnderline?
var estimateBirthDateController: MDCTextInputControllerUnderline?
var realBirthDateController: MDCTextInputControllerUnderline?
var totalNumberOfNewBornsController: MDCTextInputControllerUnderline?
var totalNumberOfDeadNewBornsController: MDCTextInputControllerUnderline?
var averageWeightOfNewBornsController: MDCTextInputControllerUnderline?
var accoucheurNameController: MDCTextInputControllerUnderline?
var newBornDeathReason1Controller: MDCTextInputControllerUnderline?
var newBornDeathReason2Controller: MDCTextInputControllerUnderline?
var newBornDeathReason3Controller: MDCTextInputControllerUnderline?
var newBornCullReason1Controller: MDCTextInputControllerUnderline?
var newBornCullReason2Controller: MDCTextInputControllerUnderline?
var newBornCullReason3Controller: MDCTextInputControllerUnderline?
var allTextFieldControllers = [MDCTextInputControllerUnderline]()
var injectedVaccinArray = [[String : Any]]()
override func viewDidLoad() {
super.viewDidLoad()
setupTextFields()
registerKeyboardNotifications()
addGestureRecognizer()
vaccinTable.dataSource = self
vaccinTable.delegate = self
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
#IBAction func closeAddNewDataPopupBtnPressed(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
#IBAction func saveNewDataBtnPressed(_ sender: Any) {
}
#IBAction func addVaccinDataBtnPressed(_ sender: UIButton) {
let getDestStoryboard = UIStoryboard(name: "AddNewData", bundle: nil)
let popupVC = getDestStoryboard.instantiateViewController(withIdentifier: "addVaccinDataVC") as! AddVaccinInfoVC
popupVC.popupDelegate = self
self.present(popupVC, animated: true, completion: nil)
}
}
extension AddNewDataVC {
func setupTextFields() {
pigTypeController = MDCTextInputControllerUnderline(textInput: pigTypeTextField)
pigTypeTextField.delegate = self
pigTypeTextField.addData(data: PIG_TYPES_ENUM.allValues)
pigTypeController?.placeholderText = "Loại lợn"
allTextFieldControllers.append(pigTypeController!)
genderController = MDCTextInputControllerUnderline(textInput: genderTextField)
genderTextField.delegate = self
genderTextField.addData(data: GENDERS)
genderController?.placeholderText = "Giới tính"
allTextFieldControllers.append(genderController!)
chipIDController = MDCTextInputControllerUnderline(textInput: chipIDTextField)
chipIDTextField.delegate = self
chipIDController?.placeholderText = "Số chip"
allTextFieldControllers.append(chipIDController!)
breedController = MDCTextInputControllerUnderline(textInput: breedTextField)
breedTextField.delegate = self
breedController?.placeholderText = "Giống"
allTextFieldControllers.append(breedController!)
subBreedController = MDCTextInputControllerUnderline(textInput: subBreedTextField)
subBreedTextField.delegate = self
subBreedController?.placeholderText = "Giống phụ"
allTextFieldControllers.append(subBreedController!)
dadIDController = MDCTextInputControllerUnderline(textInput: dadIDTextField)
dadIDTextField.delegate = self
dadIDController?.placeholderText = "Số chip bố mẹ"
allTextFieldControllers.append(dadIDController!)
momIDController = MDCTextInputControllerUnderline(textInput: momIDTextField)
momIDTextField.delegate = self
momIDController?.placeholderText = "Số chip mẹ"
allTextFieldControllers.append(momIDController!)
penIDController = MDCTextInputControllerUnderline(textInput: penIDTextField)
penIDTextField.delegate = self
penIDController?.placeholderText = "Số chuồng"
allTextFieldControllers.append(penIDController!)
weightController = MDCTextInputControllerUnderline(textInput: weightTextField)
weightTextField.delegate = self
weightController?.placeholderText = "Số kg"
allTextFieldControllers.append(weightController!)
parityController = MDCTextInputControllerUnderline(textInput: parityTextField)
parityTextField.delegate = self
parityController?.placeholderText = "Số lứa"
allTextFieldControllers.append(parityController!)
birthDateController = MDCTextInputControllerUnderline(textInput: birthDateTextField)
birthDateTextField.delegate = self
birthDateController?.placeholderText = "Ngày sinh"
allTextFieldControllers.append(birthDateController!)
weanDateController = MDCTextInputControllerUnderline(textInput: weanDateTextField)
weanDateTextField.delegate = self
weanDateController?.placeholderText = "Ngày cai sữa"
allTextFieldControllers.append(weanDateController!)
arrivalDateController = MDCTextInputControllerUnderline(textInput: arrivalDateTextField)
arrivalDateTextField.delegate = self
arrivalDateController?.placeholderText = "Ngày đến"
allTextFieldControllers.append(arrivalDateController!)
herdEntryDateController = MDCTextInputControllerUnderline(textInput: herdEntryDateTextField)
herdEntryDateTextField.delegate = self
herdEntryDateController?.placeholderText = "Ngày nhập đàn"
allTextFieldControllers.append(herdEntryDateController!)
startOffDutySowDateController = MDCTextInputControllerUnderline(textInput: startOffDutySowDateTextField)
startOffDutySowDateTextField.delegate = self
startOffDutySowDateController?.placeholderText = "Ngày nái nghỉ"
allTextFieldControllers.append(startOffDutySowDateController!)
semenFromBoarIDController = MDCTextInputControllerUnderline(textInput: semenFromBoarIDTextField)
semenFromBoarIDTextField.delegate = self
semenFromBoarIDController?.placeholderText = "Mã heo nọc"
allTextFieldControllers.append(semenFromBoarIDController!)
techicianNameController = MDCTextInputControllerUnderline(textInput: technicianNameTextField)
technicianNameTextField.delegate = self
techicianNameController?.placeholderText = "Người phối"
technicianNameTextField.addData(data: TECHNICIAN_NAMES)
allTextFieldControllers.append(techicianNameController!)
matingDateController = MDCTextInputControllerUnderline(textInput: matingDateTextField)
matingDateTextField.delegate = self
matingDateController?.placeholderText = "Ngày phối"
allTextFieldControllers.append(matingDateController!)
estimateBirthDateController = MDCTextInputControllerUnderline(textInput: estimateBirthDateTextField)
estimateBirthDateTextField.delegate = self
estimateBirthDateController?.placeholderText = "Ngày đẻ dự kiến"
allTextFieldControllers.append(estimateBirthDateController!)
realBirthDateController = MDCTextInputControllerUnderline(textInput: realBirthDateTextField)
realBirthDateTextField.delegate = self
realBirthDateController?.placeholderText = "Ngày đẻ thực tế"
allTextFieldControllers.append(realBirthDateController!)
totalNumberOfNewBornsController = MDCTextInputControllerUnderline(textInput: totalNumberOfNewBornsTextField)
totalNumberOfNewBornsTextField.delegate = self
totalNumberOfNewBornsController?.placeholderText = "Tổng heo con sinh"
allTextFieldControllers.append(totalNumberOfNewBornsController!)
totalNumberOfDeadNewBornsController = MDCTextInputControllerUnderline(textInput: totalNumberOfDeadNewBornsTextField)
totalNumberOfDeadNewBornsTextField.delegate = self
totalNumberOfDeadNewBornsController?.placeholderText = "Tổng heo con chết"
allTextFieldControllers.append(totalNumberOfDeadNewBornsController!)
averageWeightOfNewBornsController = MDCTextInputControllerUnderline(textInput: averageWeightOfNewBornsTextField)
averageWeightOfNewBornsTextField.delegate = self
averageWeightOfNewBornsController?.placeholderText = "Kg trung bình"
allTextFieldControllers.append(averageWeightOfNewBornsController!)
accoucheurNameController = MDCTextInputControllerUnderline(textInput: accoucheurNameTextField)
accoucheurNameTextField.delegate = self
accoucheurNameController?.placeholderText = "Người đỡ đẻ"
allTextFieldControllers.append(accoucheurNameController!)
newBornDeathReason1Controller = MDCTextInputControllerUnderline(textInput: newBornDeathReason1TextField)
newBornDeathReason1TextField.delegate = self
newBornDeathReason1Controller?.placeholderText = "Chết khô"
allTextFieldControllers.append(newBornDeathReason1Controller!)
newBornDeathReason2Controller = MDCTextInputControllerUnderline(textInput: newBornDeathReason2TextField)
newBornDeathReason2TextField.delegate = self
newBornDeathReason2Controller?.placeholderText = "Chết lưu"
allTextFieldControllers.append(newBornDeathReason2Controller!)
newBornDeathReason3Controller = MDCTextInputControllerUnderline(textInput: newBornDeathReason3TextField)
newBornDeathReason3TextField.delegate = self
newBornDeathReason3Controller?.placeholderText = "Chết tươi"
allTextFieldControllers.append(newBornDeathReason3Controller!)
newBornCullReason1Controller = MDCTextInputControllerUnderline(textInput: newBornCullReason1TextField)
newBornCullReason1TextField.delegate = self
newBornCullReason1Controller?.placeholderText = "Loại nhỏ"
allTextFieldControllers.append(newBornCullReason1Controller!)
newBornCullReason2Controller = MDCTextInputControllerUnderline(textInput: newBornCullReason2TextField)
newBornCullReason2TextField.delegate = self
newBornCullReason2Controller?.placeholderText = "Loại yếu"
allTextFieldControllers.append(newBornCullReason2Controller!)
newBornCullReason3Controller = MDCTextInputControllerUnderline(textInput: newBornCullReason3TextField)
newBornCullReason3TextField.delegate = self
newBornCullReason3Controller?.placeholderText = "Loại nhỏ"
allTextFieldControllers.append(newBornCullReason3Controller!)
for controller in allTextFieldControllers {
controller.activeColor = Theme.darkAccent
controller.floatingPlaceholderActiveColor = Theme.darkAccent
}
}
func addGestureRecognizer() {
let tapRecognizer = UITapGestureRecognizer(target: self,
action: #selector(tapDidTouch(sender: )))
self.scrollView.addGestureRecognizer(tapRecognizer)
}
#objc func tapDidTouch(sender: Any) {
self.view.endEditing(true)
}
func registerKeyboardNotifications() {
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(
self,
selector: #selector(keyboardWillShow(notif:)),
name: .UIKeyboardWillChangeFrame,
object: nil)
notificationCenter.addObserver(
self,
selector: #selector(keyboardWillShow(notif:)),
name: .UIKeyboardWillShow,
object: nil)
notificationCenter.addObserver(
self,
selector: #selector(keyboardWillHide(notif:)),
name: .UIKeyboardWillHide,
object: nil)
}
#objc func keyboardWillShow(notif: Notification) {
guard let frame = notif.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect else {
return
}
scrollView.contentInset = UIEdgeInsets(top: 0.0,
left: 0.0,
bottom: frame.height,
right: 0.0)
}
#objc func keyboardWillHide(notif: Notification) {
scrollView.contentInset = UIEdgeInsets()
}
func toggleFarrowInfoInputsStackView(toggle: Bool) {
if toggle {
sowInfoInputsStackView.isHidden = false
} else {
sowInfoInputsStackView.isHidden = true
}
}
func toggleGiltInputs(toggle: Bool) {
if toggle {
giltInfoInputsStackView.isHidden = false
} else {
giltInfoInputsStackView.isHidden = true
}
}
func toggleOffDutySowInputs(toggle: Bool) {
if toggle {
startOffDutySowDateTextField.isHidden = false
} else {
startOffDutySowDateTextField.isHidden = true
}
}
func toggleMatingInputs(toggle: Bool) {
if toggle {
matingInfoInputsStackView.isHidden = false
} else {
matingInfoInputsStackView.isHidden = true
}
}
func toggleFarrowInputs(toggle: Bool) {
if toggle {
farrowInfoInputsStackView.isHidden = false
} else {
farrowInfoInputsStackView.isHidden = true
}
}
func toggleParityTextField(toggle: Bool) {
if toggle {
parityTextField.isHidden = false
} else {
parityTextField.isHidden = true
}
}
}
extension AddNewDataVC: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return false
}
func textFieldDidEndEditing(_ textField: UITextField) {
if let textField = textField as? PickerTextField {
let text = textField.text?.lowercased()
if !textField.isDatePicker && textField == pigTypeTextField {
if text!.contains("nái") || textField.text! == PIG_TYPES_ENUM.gilt.rawValue {
toggleFarrowInfoInputsStackView(toggle: true)
if textField.text! == PIG_TYPES_ENUM.gilt.rawValue {
toggleGiltInputs(toggle: true)
toggleOffDutySowInputs(toggle: false)
toggleMatingInputs(toggle: false)
toggleFarrowInputs(toggle: false)
} else if textField.text! == PIG_TYPES_ENUM.offDutySow.rawValue {
toggleGiltInputs(toggle: true)
toggleOffDutySowInputs(toggle: true)
toggleMatingInputs(toggle: false)
toggleFarrowInputs(toggle: false)
} else if textField.text! == PIG_TYPES_ENUM.matingSow.rawValue {
toggleGiltInputs(toggle: true)
toggleOffDutySowInputs(toggle: false)
toggleMatingInputs(toggle: true)
toggleFarrowInputs(toggle: false)
} else if textField.text! == PIG_TYPES_ENUM.farrow.rawValue {
toggleGiltInputs(toggle: true)
toggleOffDutySowInputs(toggle: false)
toggleMatingInputs(toggle: true)
toggleFarrowInputs(toggle: true)
}
} else {
toggleFarrowInfoInputsStackView(toggle: false)
toggleGiltInputs(toggle: false)
toggleOffDutySowInputs(toggle: false)
toggleMatingInputs(toggle: false)
toggleFarrowInputs(toggle: false)
if textField.text! == PIG_TYPES_ENUM.boar.rawValue {
genderTextField.text = "Đực"
genderTextField.isUserInteractionEnabled = false
} else {
genderTextField.text = ""
genderTextField.isUserInteractionEnabled = true
}
}
} else if !textField.isDatePicker && textField == genderTextField {
if textField.text == "Cái" {
toggleParityTextField(toggle: true)
} else {
toggleParityTextField(toggle: false)
}
}
}
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if textField is PickerTextField {
textField.resignFirstResponder()
return false
} else {
return true
}
}
}
extension AddNewDataVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return injectedVaccinArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = vaccinTable.dequeueReusableCell(withIdentifier: "injectedVaccinCell", for: indexPath) as? InjectedVaccinCell else {
return UITableViewCell()
}
cell.configureCell(value: injectedVaccinArray[indexPath.row])
return cell
}
}
extension AddNewDataVC: PopupDelegates {
func popupValueSelected(value: [String : Any]) {
self.injectedVaccinArray.append(value)
self.vaccinTable.reloadData()
}
}
There are alot of room for improvement I know but I'm just learned swift so sorry if my code make you itch haha. right now I'm just focusing on make it works and will try to clean it up later down the road.
I have a viewcontroller that has a tableview and a button at the bottom. Within each cell is a radio button as a tapGesture. I would like to updated the button with the number of cells selected. If my gesture is in the custom cell and my button is in my viewcontroller how can I get the two to work together?
Custom cell:
class SearchTalentCell: UITableViewCell {
#IBOutlet weak var userProfileImage: UIImageView!
#IBOutlet weak var talentUserName: UILabel!
#IBOutlet weak var selectedImg: UIImageView!
#IBOutlet weak var inviteSentImg: UIImageView!
var prospectRef: FIRDatabaseReference!
var currentTalent: UserType!
func setTalent(talent: UserType) {
currentTalent = talent
currentTalent.userKey = talent.userKey
}
override func awakeFromNib() {
super.awakeFromNib()
let tap = UITapGestureRecognizer(target: self, action: #selector(selectTapped))
tap.numberOfTapsRequired = 1
selectedImg.addGestureRecognizer(tap)
selectedImg.isUserInteractionEnabled = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func configureCell(user: UserType, img: UIImage? = nil) {
prospectRef = Cast.REF_PRE_PRODUCTION_CASTING_POSITION.child(ProjectDetailVC.currentProject).child(FIRDataCast.prospect.rawValue).child(CastingDetailVC.positionName).child(user.userKey)
setTalent(talent: user)
self.talentUserName.text = "\(user.firstName) \(user.lastName)"
prospectRef.observeSingleEvent(of: .value, with: { (snapshot) in
if let _ = snapshot.value as? NSNull {
self.inviteSentImg.isHidden = true
} else {
self.inviteSentImg.image = UIImage(named: "inviteSent")
self.inviteSentImg.isHidden = false
}
})
if UserType.selectedTalentForSearch.contains(currentTalent.userKey) {
selectedImg.image = UIImage(named: "radioSelected")
} else {
selectedImg.image = UIImage(named: "radioUnselected")
}
//Image Caching
if img != nil {
self.userProfileImage.image = img
} else {
if let imageURL = user.profileImage {
let ref = FIRStorage.storage().reference(forURL: imageURL)
ref.data(withMaxSize: 2 * 1024 * 1024, completion: { (data, error) in
if error != nil {
print("ZACK: Unable to download image from Firebase Storage")
} else {
print("ZACK: Image downloaded from Firebase Storage")
if let imgData = data {
if let img = UIImage(data: imgData) {
self.userProfileImage.image = img
SearchTalentVC.userProfileImageCache.setObject(img, forKey: imageURL as NSString)
}
}
}
})
}
}
}
#objc func selectTapped(sender: UITapGestureRecognizer) {
if UserType.selectedTalentForSearch.contains(currentTalent.userKey) {
selectedImg.image = UIImage(named: "radioUnselected")
UserType.selectedTalentForSearch = UserType.selectedTalentForSearch.filter{$0 != currentTalent.userKey}
print("Keys: \(UserType.selectedTalentForSearch)")
} else {
selectedImg.image = UIImage(named: "radioSelected")
UserType.selectedTalentForSearch.append(currentTalent.userKey)
print("Keys: \(UserType.selectedTalentForSearch)")
}
}
}
ViewController:
class SearchTalentVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var sendInviteButton: UIButton!
var searchingRole = [Cast]()
var unfilteredTalent = [UserType]()
var filteredTalent = [UserType]()
var selectedTalent = [UserType]()
var matchingTalentUserKeys = [String]()
var isFiltered = false
var selectedCounter = [String]()
var prospectRef: FIRDatabaseReference!
static var userProfileImageCache: NSCache<NSString, UIImage> = NSCache()
let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search Talent"
searchController.searchBar.barStyle = .black
navigationItem.searchController = searchController
definesPresentationContext = true
searchController.searchBar.scopeButtonTitles = ["All", "Role Specific"]
searchController.searchBar.tintColor = UIColor.white
searchController.searchBar.delegate = self
searchController.searchResultsUpdater = self
self.sendInviteButton.setTitle("Send Invite to \(UserType.selectedTalentForSearch.count) Prospects", for: .normal)
getTalentProfiles()
}
Thank you for any help!
I'm not sure why you are using the cell selection inside the cell, as opposed to the tableview delegate function func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)?
If you use didSelectRowAt, you could have an array of selected rows and you can include the selectedRows.count into your button text.
Hope that helps!
I am loading a views from nib and i am successfully loaded but first one is loaded perfect but in second view getting nil outlets. below is my code.
Set a global variable to loadview by default is is 0 and it is increase when i press next button.
User is struct here :
struct User {
static var quizIndexNo = 0
}
This method is in my ViewController
let moptViewInstance = MOPT()
let rmkViewInstance = RMK()
getting view name from this array:
let viewName = ["MOPT","RMK"]
func loadQuizView(){
if viewName[User.quizIndexNo] == "MOPT" {
for views in vwOptionView.subviews {
views.removeFromSuperview()
}
moptViewInstance.prepareScreenWithView(navigationController: UINavigationController(), viewSize: self.vwOptionView, viewController: self)
} else if viewName[User.quizIndexNo] == "RMK" {
for views in vwOptionView.subviews {
views.removeFromSuperview()
}
rmkViewInstance.prepareScreenWithView(navigationController: UINavigationController(), viewSize: self.vwOptionView, viewController: self)
}
}
// NIB View Classes
class MOPT: UIView {
#IBOutlet weak var btnPrevious: UIButton!
#IBOutlet weak var btnNext: UIButton!
var nibView: UIView!
var instanceOfQuizController : QuizCointroller!
func prepareScreenWithView(navigationController: UINavigationController, viewSize: UIView, viewController: UIViewController) {
nibView = Bundle.main.loadNibNamed("MOPT", owner: self, options: nil)?[0] as! UIView
nibView.tag = 200
var tempRect = nibView.frame
print(tempRect)
if User.quizIndexNo == 0 {
btnPrevious.isHidden = true
}
if User.quizIndexNo == 0 {
btnNext.setTitle("Test", for: .normal)
}
print("Index No is: \(User.quizIndexNo) and \(Sequence.totalQuizQuestionCout)")
if User.quizIndexNo == Sequence.totalQuizQuestionCout - 1 {
btnNext.setTitle("Submit", for: .normal)
}
instanceOfQuizController = viewController as! QuizCointroller
tempRect = CGRect(x: 0, y: 0, width: viewSize.bounds.width, height: viewSize.bounds.height)
viewSize.addSubview(self.nibView)
self.nibView.frame = tempRect
}
#IBAction func btnPrev(_ sender: UIButton) {
User.quizIndexNo -= 1
Sequence.instanceOfQuizControllerTest.previousButtonPressed()
}
// Next button will reload next view
#IBAction func btnNext(_ sender: UIButton) {
User.quizIndexNo += 1
// here sequence is global variable of type ViewController
Sequence.instanceOfQuizControllerTest.nextButtonPressed()
}
}
Second NibView Class
class RMK: UIView {
#IBOutlet weak var btnPrevious: UIButton!
#IBOutlet weak var btnNext: UIButton!
var nibView: UIView!
var instanceOfQuizControllerTest : QuizCointroller!
func prepareScreenWithView(navigationController: UINavigationController, viewSize: UIView, viewController: UIViewController) {
nibView = Bundle.main.loadNibNamed("RMK", owner: self, options: nil)?[0] as! UIView
nibView.tag = 200
var tempRect = nibView.frame
print(tempRect)
if User.quizIndexNo == 1 {
btnPrevious.isHidden = true //app is crashing here when i am trying to set title Button is showing nil
}
if User.quizIndexNo == 1 {
btnNext.setTitle("Submit", for: .normal)
}
instanceOfQuizControllerTest = viewController as! QuizCointroller
print("Quiz ViewController instatnce \(instanceOfQuizControllerTest)")
tempRect = CGRect(x: 0, y: 0, width: viewSize.bounds.width, height: viewSize.bounds.height)
viewSize.addSubview(self.nibView)
self.nibView.frame = tempRect
}
#IBAction func btnPrev(_ sender: UIButton) {
User.quizIndexNo -= 1
Sequence.instanceOfQuizControllerTest.previousButtonPressed()
}
#IBAction func btnNext(_ sender: UIButton) {
print(instanceOfQuizControllerTest)
User.quizIndexNo += 1
Sequence.instanceOfQuizControllerTest.nextButtonPressed()
}
}