Format data content in Tableviewcell in Swift - ios

How it should look like.
How it currently look like.
I'm trying to display information on my tableview cell.
The first cell information on the image above looks good, but only when the table view is on edit mode - and I only want the same display in normal mode for all my cells.
Here is my code below
//cellForRow method
var cell = UITableViewCell(style: UITableViewCellStyle.value1, reuseIdentifier: celliD)
cell?.textLabel?.numberOfLines = 0
cell?.detailTextLabel?.numberOfLines = 0
cell?.accessoryView = nil
cell?.tintColor = UIColor.cmoOrangeColor
cell?.textLabel?.textColor = UIColor.darkGray
cell?.detailTextLabel?.textColor = UIColor.lightGray
let animalEntity = self.newSaleSelectedAnimalsManagedObject[indexPath.row] as? AnimalEntity
cell?.textLabel?.attributedText = AnimalFacade.animalTitleAttributedText(animalEntity: animalEntity!, withHolding: false)
cell?.detailTextLabel?.attributedText = AnimalFacade.animalDetails()
return cell!
//textLabel formating data
class func animalTitleAttributedText(animalEntity: AnimalEntity, withHolding: Bool) -> NSMutableAttributedString {
//AttributedText
let attributedTitle = NSDictionary(object: UIFont.tableViewCellTitle as Any, forKey: NSFontAttributeName as NSCopying) as? [String : Any]
let attributedSubtitle = NSDictionary(object: UIFont.tableViewCellSubtitle as Any, forKey: NSFontAttributeName as NSCopying) as? [String : Any]
//TextLabel
let titleAttributedText = NSMutableAttributedString()
//officialTag
let officialTag = animalEntity.officialTag //UK 123456 123456
let mgtTag = animalEntity.managementTag //WER3456
let age = DateUtil.calculateAge(dateTime: animalEntity.dob! as Date) //13 y
let animalCategory = animalEntity.animalTag //Heifer Calf
let breed = animalEntity.breed //AB
titleAttributedText.append(NSAttributedString(string: officialTag! + "\n", attributes: attributedTitle))
titleAttributedText.append(NSAttributedString(string: "Mgmt Tag: \(mgtTag!), \(age), \(animalCategory!), \(breed!) \n", attributes: attributedSubtitle))
return titleAttributedText
}
//detailLabel formatting data
class func animalDetails() -> NSMutableAttributedString {
let attributedSubtitle = NSDictionary(object: UIFont.tableViewCellSubtitle as Any, forKey: NSFontAttributeName as NSCopying) as? [String : Any]
//detailsLabel
let detailsAttributedText = NSMutableAttributedString()
let price = "1234.85"
let lotNumber = "TREPOU123"
detailsAttributedText.append(NSAttributedString(string: price + "\n\n", attributes: attributedSubtitle))
detailsAttributedText.append(NSAttributedString(string: lotNumber, attributes: attributedSubtitle))
return detailsAttributedText
}

Related

Upload Empty Strings to Firebase Realtime Database

I'm trying to upload a child nod to a reference to my Firebase Realtime Database, however I'm running into an issue. I'm trying to have my secondDateAndTimes and thirdDateAndTimes upload as empty strings if they are not filled out, but my handleConfirm() will only work if the two are filled out. What do I need to do so the child node uploads even if the two UILabels are empty/not showing? Thank you!
JobRequest Model
struct JobRequest {
let uid: String
let fullname: String
let username: String
let address: String
let firstDateAndTimes: String
let secondDateAndTimes: String
let thirdDateAndTimes: String
let timeConstraints: String
let jobDescription: String
init(dictionary: [String : Any]) {
self.uid = dictionary["uid"] as? String ?? ""
self.fullname = dictionary["fullname"] as? String ?? ""
self.username = dictionary["username"] as? String ?? ""
self.address = dictionary["address"] as? String ?? ""
self.firstDateAndTimes = dictionary["firstDateAndTimes"] as? String ?? ""
self.secondDateAndTimes = dictionary["secondDateAndTimes"] as? String ?? ""
self.thirdDateAndTimes = dictionary["thirdDateAndTimes"] as? String ?? ""
self.timeConstraints = dictionary["timeConstraints"] as? String ?? ""
self.jobDescription = dictionary["jobDescription"] as? String ?? ""
}
}
API Service
struct JobDetailCredentials {
var uid: String
var fullname: String
var username: String
var address: String
var firstDateAndTimes: String
var secondDateAndTimes: String
var thirdDateAndTimes: String
var timeConstraints: String
var jobDescription: String
}
// MARK: - CustomerService
struct CustomerService {
static func uploadCustomerAndJobRequest(jobDetails: JobDetailCredentials, completion: #escaping(DatabaseCompletion)) {
guard let uid = Auth.auth().currentUser?.uid else { return }
let values = ["uid" : jobDetails.uid,
"fullname" : jobDetails.fullname,
"username" : jobDetails.username,
"address" : jobDetails.address,
"firstDateAndTimes" : jobDetails.firstDateAndTimes,
"secondDateAndTimes" : jobDetails.secondDateAndTimes,
"thirdDateAndTimes" : jobDetails.thirdDateAndTimes,
"timeConstraints" : jobDetails.timeConstraints,
"jobDescription" : jobDetails.jobDescription] as [String : Any]
REF_CUSTOMERS.child(uid).child("job-request-details").childByAutoId().updateChildValues(values, withCompletionBlock: completion)
}
}
RequestJobConfirmationController
lazy var secondDateAndTimeDetailsLabel: UILabel = {
let label = UILabel()
label.textColor = .black
label.textAlignment = .center
label.font = UIFont(name: "AvenirNext-MediumItalic", size: 14)
label.numberOfLines = 0
return label
}()
lazy var thirdDateAndTimeDetailsLabel: UILabel = {
let label = UILabel()
label.textColor = .black
label.textAlignment = .center
label.font = UIFont(name: "AvenirNext-MediumItalic", size: 14)
label.numberOfLines = 0
return label
}()
#objc func handleConfirm() {
guard let uid = Auth.auth().currentUser?.uid ,
let fullname = fullnameDetailsLabel.text ,
let username = customer?.username ,
let address = addressDetailsLabel.text ,
let firstDateAndTimes = firstDateAndTimeDetailsLabel.text ,
let secondDateAndTimes = secondDateAndTimeDetailsLabel.text ,
let thirdDateAndTimes = thirdDateAndTimeDetailsLabel.text ,
let timeConstraints = timeConstraintsDetailsLabel.text ,
let jobDescription = jobDescriptionDetailsLabel.text else { return }
let jobDetails = JobDetailCredentials(uid: uid, fullname: fullname, username: username, address: address,
firstDateAndTimes: firstDateAndTimes, secondDateAndTimes: secondDateAndTimes,
thirdDateAndTimes: thirdDateAndTimes, timeConstraints: timeConstraints,
jobDescription: jobDescription)
CustomerService.uploadCustomerAndJobRequest(jobDetails: jobDetails) { error, ref in
if let _ = error {
self.simpleAlert(title: "Error", msg: "Unable to upload job details, please try again later.")
return
}
let controller = FindEmployeeJobRequestController()
controller.modalPresentationStyle = .fullScreen
self.present(controller, animated: true, completion: nil)
}
}
Instead of putting your secondDateAndTimes and thirdDateAndTimes inside the guard, which will guarantee that the function returns if they're nil, move them outside of that guard and optionally bind them:
guard let uid = Auth.auth().currentUser?.uid ,
let fullname = fullnameDetailsLabel.text ,
let username = customer?.username ,
let address = addressDetailsLabel.text ,
let firstDateAndTimes = firstDateAndTimeDetailsLabel.text ,
let timeConstraints = timeConstraintsDetailsLabel.text ,
let jobDescription = jobDescriptionDetailsLabel.text else { return }
let secondDateAndTimes = secondDateAndTimeDetailsLabel.text ?? "",
let thirdDateAndTimes = thirdDateAndTimeDetailsLabel.text ?? "",
//...
I figured what my problem was, I wasn't setting empty strings as the texts for my UILabels.
RequestJobConfirmationController
lazy var secondDateAndTimeDetailsLabel: UILabel = {
let label = UILabel()
label.text = ""
label.textColor = .black
label.textAlignment = .center
label.font = UIFont(name: "AvenirNext-MediumItalic", size: 14)
label.numberOfLines = 0
return label
}()
lazy var thirdDateAndTimeDetailsLabel: UILabel = {
let label = UILabel()
label.text = ""
label.textColor = .black
label.textAlignment = .center
label.font = UIFont(name: "AvenirNext-MediumItalic", size: 14)
label.numberOfLines = 0
return label
}()

Add text with different style to a existing label

I have a label with text and want to add more test in running time, but I want to add different style to this text that was add. Is there a way to do this?
This is the code
label.text = (label.text ?? "") + " \n \(userName)"
How do I add style to userName without changing the style of the label?
use attributed text in UILabel:
here some code.
a) some useful typedefs:
typealias AttrDict = [NSAttributedString.Key : Any]
a) create some styles:
func textAttribute() -> AttrDict{
let textFont = UIFont.systemFont(ofSize: 32)
let stdAttrib = [NSAttributedString.Key.font: textFont,
//NSParagraphStyleAttributeName: paragraphStyle2,
NSAttributedString.Key.foregroundColor: UIColor.red] as AttrDict
return stdAttrib
}
func smallTextAttribute() -> AttrDict{
let textFont = UIFont.systemFont(ofSize: 10)
let stdAttrib = [NSAttributedString.Key.font: textFont,
NSAttributedString.Key.foregroundColor: UIColor.green] as AttrDict
return stdAttrib
}
c) build Your attributed String:
func myAttributedString() -> NSAttributedString {
let pieces = ["hello", "word"]
let resultAttributed = NSMutableAttributedString()
var s = ""
s = pieces[0] + "\n"
resultAttributed.append(NSAttributedString(string: s,
attributes: stdTextAttribute() ))
s = pieces[1] + "\n"
resultAttributed.append(NSAttributedString(string: s,
attributes: smallTextAttribute() ))
return resultAttributed
}
d) put in Your label/textView:
....
class ViewController: UIViewController {
#IBOutlet weak var myLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
myLabel.numberOfLines = 0
myLabel.attributedText = myAttributedString()
}
}
I made a GIST:
https://gist.github.com/ingconti/aefc78c6d0b22f5329f906094c312a21
PLS connect UIlabel..
:)
To do this, you need to use NSMutableAttributedString, NSAttributedString and use label.attributedText, How?
Doing this:
let userName = "StackOverflow"
let prefixText = NSAttributedString(string: "this is normal ")
let font = UIFont.systemFont(ofSize: 40)
let attributes: [NSAttributedString.Key: Any] = [
.font: font,
.foregroundColor: UIColor.blue
]
let userNameWithStyle = NSAttributedString(string: userName, attributes: attributes)
let finalString = NSMutableAttributedString(attributedString: prefixText)
finalString.append(userNameWithStyle)
self.label.attributedText = finalString
Image result

How to display dynamic multiple label in tableview cell swift?

I'm trying with NSMutableAttributedString but not getting perfect resolution and also underline for each string.
Now It's display like this:
But I want like this:
I m trying with this code in tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) for displaying the cell:
let arrSearchTag = search_detail?.value(forKey: "search_tags") as! NSArray
if arrSearchTag.count > 0
{
let str : NSMutableAttributedString = NSMutableAttributedString(string: "")
for string in arrSearchTag
{
let myString = string
let myString1 = " "
let myAttribute = [NSBackgroundColorAttributeName : UIColor.init(red: 94.0/255.0, green: 94.0/255.0, blue: 94.0/255.0, alpha: 1.0)]
let myAttribute1 = [NSBackgroundColorAttributeName : UIColor.clear]
let range = (myString as! NSString).range(of: myString as! String)
let myAttrString = NSMutableAttributedString(string: myString as! String, attributes: myAttribute)
let myAttrString1 = NSMutableAttributedString(string: myString1 , attributes: myAttribute1)
myAttrString.addAttribute(NSForegroundColorAttributeName, value: UIColor.white, range: range)
str.append(myAttrString)
str.append(myAttrString1)
}
cell.lblSearchTags.attributedText = str
}

didSelectRowAt indexPath method called after long pressing the UITableViewCell

I'm developing a simple shopping app. There I used UITableView for listing the product but when I select the listed product in the particular cell, "didSelectRowAt indexPath" method has not been called/triggered, so I tried with long pressing UITableViewCell the method is working good and also triggered properly but I don't need this solution.
In the product listing page, I just used UISegmentedControl in the navigation bar and dynamic prototyped UITableView in the UIView. Even I didn't use any kind of UIGestures in this page.
This question may be duplicated and already asked in Stack Overflow, but there were none of the answers solved my problem. I need to continue working the UITableViewCell without long pressing.
Note: I tried switching off the "Delays Content Touches" in TableView, and I surf through Stack Overflow and web but I couldn't find any solutions.
Update
"cellForRowAt indexPath" code are as follows:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! ProductCell
let vendor = array_list_vendor[indexPath.row] as? String
let orgPrice = array_list_price[indexPath.row] as? Int
let starDealPrice = array_list_stardealPrice[indexPath.row] as? Int
let url = array_list_image[indexPath.row] as! String
cell.productTitle.text = array_list_title[indexPath.row] as? String
if url == "" {
cell.productImg.image = UIImage(named: "no-img")
}
else {
cell.productImg.image = nil
ImageLoader.sharedLoader.imageForUrl(urlString: (url), completionHandler:{(image: UIImage?, url: String) in
//cell.productImg.frame.width =
cell.productImg.image = image!
})
}
if vendor == "amazon" {
cell.sellerImg.image = UIImage(named: "prodicon-amazon")
}
else if vendor == "flipkart" {
cell.sellerImg.image = UIImage(named: "prodicon-flipkart")
}
else {
cell.sellerImg.image = UIImage(named: "prodicon-amazon")
}
cell.starDealImg.image = UIImage(named: "prodicon-stardeal")
let rupee = "\u{20B9}"
let text = String(format: "%# %d", rupee, orgPrice!)
let linkTextWithColor = String(rupee)
let range = (text as NSString).range(of: linkTextWithColor!)
let attributedString = NSMutableAttributedString(string:text)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.black , range: range)
//Seller price
cell.sellerPrice.attributedText = attributedString
let text1 = String(format: "%# %d", rupee, starDealPrice!)
let linkTextWithColor1 = String(rupee)
let range1 = (text1 as NSString).range(of: linkTextWithColor1!)
let attributedString1 = NSMutableAttributedString(string:text1)
attributedString1.addAttribute(NSForegroundColorAttributeName, value: UIColor(red: 127.0/255.0, green: 63.0/255.0, blue: 152.0/255.0, alpha: 1.0) , range: range1) //Purple color
//Stardeal price
cell.starDealPrice.attributedText = attributedString1
let cashBack = orgPrice! - starDealPrice!
let text2 = String(format: "Save %#", rupee)
let linkTextWithColor2 = String(rupee)
let range2 = (text2 as NSString).range(of: linkTextWithColor2!)
let attributedString2 = NSMutableAttributedString(string:text2)
attributedString2.addAttribute(NSForegroundColorAttributeName, value: UIColor.white , range: range2)
let text3 = String(format: "%d", cashBack)
let linkTextWithColor3 = String(cashBack)
let range3 = (text3 as NSString).range(of: linkTextWithColor3)
let attributedString3 = NSMutableAttributedString(string:text3)
attributedString3.addAttribute(NSForegroundColorAttributeName, value: UIColor.white , range: range3)
//Attributed string with multiple words
attributedString2.append(attributedString3)
cell.productCashBack.attributedText = attributedString2
return cell
}

Creating special UIButtons text from substring in Swift

I am trying to create a special button text based off of a string that I am building from information from a user. I think I am doing this right, but the IDE is telling me that
/ 'NSDictionary' is not implicitly convertible to '[NSObject : AnyObject]'; did you mean to use 'as' to explicitly convert?
But I am doing that here
let attrString = NSMutableAttributedString(
string: substring1 as String,
attributes: NSDictionary(
object: font!,
forKey: NSFontAttributeName) as [NSObject : AnyObject])
What am I doing wrong here? Here is the whole code for this:
//applying the line break mode
customerInfoButton?.titleLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping;
var buttonText: NSString = "Fight club \n" +
points + " pt. \n" +
"rank:" + myRank
//getting the range to separate the button title strings
var newlineRange: NSRange = buttonText.rangeOfString("\n")
//getting both substrings
var substring1: NSString = ""
var substring2: NSString = ""
var substring3: NSString = ""
if(newlineRange.location != NSNotFound) {
substring1 = buttonText.substringToIndex(newlineRange.location)
substring2 = buttonText.substringFromIndex(newlineRange.location)
substring3 = buttonText.substringFromIndex(newlineRange.location)
}
//assigning diffrent fonts to both substrings
let font:UIFont? = UIFont(name: "Arial", size: 12.0)
let attrString = NSMutableAttributedString(
string: substring1 as String,
attributes: NSDictionary(
object: font!,
forKey: NSFontAttributeName) as [NSObject : AnyObject])
let attrString3 = NSMutableAttributedString(
string: substring3 as String,
attributes: NSDictionary(
object: font!,
forKey: NSFontAttributeName) as [NSObject : AnyObject])
let pointFont:UIFont? = UIFont(name: "Arial", size: 15.0)
let attrString1 = NSMutableAttributedString(
string: substring2 as String,
attributes: NSDictionary(
object: pointFont!,
forKey: NSFontAttributeName) as [NSObject : AnyObject])
//appending both attributed strings
attrString.appendAttributedString(attrString1)
//assigning the resultant attributed strings to the button
customerInfoButton?.setAttributedTitle(attrString, forState: UIControlState.Normal)
You can create your attributed string in this way:
let attributes = [NSFontAttributeName: font!]
let attrString = NSMutableAttributedString(string: substring1 as String, attributes: attributes)

Resources