Localization in iOS 11 , swift 4 - localization

I've got a problem after I upgrading to iOS 11 and Xcode version changes to 9.
When I choose the "Burmese" language, "Setting" menu text does not translate but the rest menu texts are translated into Burmese language.
var TableArray = [["Home","Buy", "Watch Later"],["Notification","Settings","User Guide"]]
Menu texts put in array and that locates in table view cell.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: TableArray[indexPath.section][indexPath.row], for: indexPath) as UITableViewCell
cell.imageView?.image = menuIconImage[indexPath.section][indexPath.row]
cell.textLabel?.text = NSLocalizedString(TableArray[indexPath.section][indexPath.row], comment: "")
cell.textLabel?.font = UIFont(name: "Tharlon", size: 17)
cell.selectionStyle = UITableViewCellSelectionStyle.blue
tableView.rowHeight = 56.0;
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
prefs.setValue(false, forKey: "FLAG")
prefs.setValue(true, forKey: "DRAWER")
debugPrint("Click LogIn")
let cell = tableView.dequeueReusableCell(withIdentifier: TableArray[indexPath.section][indexPath.row], for: indexPath) as UITableViewCell
cell.imageView?.image = menuIconImage[indexPath.section][indexPath.row]
cell.textLabel?.font = UIFont(name: "Tharlon", size: 17)
cell.textLabel?.text = NSLocalizedString(TableArray[indexPath.section][indexPath.row], comment: "")
}
However I tried , all the texts are changed to "Burmese" except "Settings" text. So, I add following codes again inside table function but it does not work.
if (cell.textLabel?.text == "Settings") {
cell.textLabel?.text = NSLocalizedString(TableArray[indexPath.section][indexPath.row], comment: "")
cell.textLabel?.font = UIFont(name: "Tharlon", size: 17)
}
Can anyone help me please? I'm still finding solution for this since last 2 days. :(

if Language.currentLanguage() == "ar"
{
cell.textLabel?.textAlignment = .right
}
else
{
cell.textLabel?.textAlignment = .left
}
this worked with me

Related

Can't select or edit Textfield inside Tableview cell

I have a controller EditProfileController: UITableViewController and a cell EditProfileCell: UITableViewCell
extension EditProfileController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! EditProfileCell
cell.delegate = self
return cell
}
}
My EditProfileCell
This is my TextField:
class EditProfileCell: UITableViewCell {
lazy var infoTextField: UITextField = {
let tf = UITextField()
tf.borderStyle = .none
tf.font = UIFont.systemFont(ofSize: 14)
tf.textAlignment = .left
tf.textColor = .white
tf.isUserInteractionEnabled = true
return tf
}()
}
The Problem: I can edit the infos for the textfields using the simulator. But when I'm running the app on my iPhone, I'm not able to even select the Textfield, not even the keyboard shows up.
I've tested adding cell.infoTextField.becomeFirstResponder() on the extension, and it works, but this makes only the last textfield become editable.
What I'm doing wrong?
You have to set contentView.isUserInteractionEnabled to false
extension EditProfileController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! EditProfileCell
cell.delegate = self
cell.contentView.isUserInteractionEnabled = false
return cell
}
}

Swift resize uitablecell image

I just set my UITableCell linebreak to byWordWrapping and add this method:
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Now My UITableCell Images are massive, what is the best way to resize them or have the images aspect to fit?
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "commentsCell", for: indexPath)
cell.textLabel?.numberOfLines = 0
cell.textLabel?.lineBreakMode = .byWordWrapping
cell.detailTextLabel?.numberOfLines = 0
cell.detailTextLabel?.lineBreakMode = .byWordWrapping
if((self.array[indexPath.row]["profileImg"] as! String) == "")
{
cell.textLabel?.text = (self.array[indexPath.row]["username"] as! String)
cell.detailTextLabel?.text = (self.array[indexPath.row]["comment"] as! String)
cell.imageView?.image = UIImage(named: "default.png")
}
else
{
let imgUrl = URL(string:"http://auxpod.com/uploads/" + (self.array[indexPath.row]["profileImg"] as! String))
Alamofire.request(imgUrl!).responseImage { response in
DispatchQueue.main.async {
if let image = response.result.value {
cell.textLabel?.text = (self.array[indexPath.row]["username"] as! String)
cell.detailTextLabel?.text = (self.array[indexPath.row]["comment"] as! String)
cell.imageView?.image = image
}
}
}
}
return cell
}
1-
Don't load the image inside cellForRowAt as it keeps download the image every scroll so use SDWebImage that caches it after first download
2-
Create a custom cell class , hook the the height constraint of the imageView and change it according to the required aspect ratio
imageViewH.constant = imageRealHeight * imageCellWidth / imageRealWidth

UITableView background colour for bottom 5 rows

I do know how to input background colours for my row, but I don't really know how I can filter it by only the bottom 5 rows are "cell.backgroundColor = UIColor.red;" whereas the rest stays the same. Appreciate those who can help me this thanks!
P.S: Sorry as my swift is quite rusty.
UITableView Controller
import UIKit
import FirebaseDatabase
var postData2 = [String]()
var postData3 = [String]()
var tableDataArray = [tableData]()
class ResultsController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
ref = Database.database().reference() //set the firebase reference
// Retrieve the post and listen for changes
databaseHandle = ref?.child("Posts3").observe(.value, with: { (snapshot) in
postData2.removeAll()
postData3.removeAll()
tableDataArray.removeAll()
for child in snapshot.children {
let snap = child as! DataSnapshot
let key = snap.key
let value = String(describing: snap.value!)
let rating = (value as NSString).integerValue
postData2.append(key)
postData3.append(value)
tableDataArray.append(tableData(boothName: key, boothRating: rating))
}
postData2.removeAll()
postData3.removeAll()
let sortedTableData = tableDataArray.sorted(by: { $0.boothRating > $1.boothRating })
for data in sortedTableData {
postData2.append(data.boothName)
let value = String(describing: data.boothRating)
postData3.append(value)
}
self.tableView.reloadData()
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return postData2.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.font = UIFont.init(name: "Helvetica", size: 23)
cell.textLabel?.text = postData2[indexPath.row]
cell.detailTextLabel?.text = postData3[indexPath.row] + " ♥"
cell.detailTextLabel?.textColor = UIColor.red;
cell.detailTextLabel?.font = UIFont.init(name: "Helvetica", size: 23)
// cell.backgroundColor = UIColor.red;
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return 80
}
}
class tableData {
var boothName: String
var boothRating: Int
init(boothName: String, boothRating: Int) {
self.boothName = boothName
self.boothRating = boothRating
}
}
A simple way is to have an conditional check to see if the indexPath.row value is within the last five.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if(indexPath.row >= postData2.count-5){
cell.backgroundColor = UIColor.red
}else{
cell.backgroundColor = UIColor.white /* Remaining cells */
}
return cell
}
Some of the other answers will work - but it is nicer to use cells that have a known configuration when they are dequeued by cellForRowAt, not deal with a bunch of possible starting conditions each time you dequeue a cell. To do this subclass the UITableViewCell and override prepareForReuse(). This function will be called just before a cell is returned by dequeueReusableCell. Then cells can be set to a known starting point before you configure them. If cells could be received configured any possible way in cellForRowAt, you soon wind up with a very long function with a lot of if/else conditions.
The condition
if indexPath.row >= postData2.count - 5 {
cell.backgroundColor = UIColor.red
}
can be used as it is, and prepareForReuse takes care of the cells not keeping any settings when they are recycled. Here's an example:
override func prepareForReuse() {
super.prepareForReuse()
backgroundColor = UIColor.white
}
With this one simple setting it's a wash whether you do the if/else approach or use subclassing to make the most of prepareForReuse. But as soon as you have more than one thing to set in a cell you will find it is far less complex to use this function and results in far fewer mistakes with the appearance of cells - consider what would happen if there were more than one possible color a cell could be, or there were multiple elements in the cell to be configured with multiple possible values...
You can add simple logic
if indexPath.row >=(postData2.count-5) {
cell.backgroundColor = UIColor.red
}else {
cell.backgroundColor = UIColor.white
}
Just check a condition for setting the red colour for last five rows.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if(indexPath.row >= postData2.count-5){
cell.backgroundColor = UIColor.red;
}else {
cell.backgroundColor = UIColor.white; //white colour for other rows
}
return cell
}
This method is recommended by the system, this method is more circumventing reuse in some cases (like when you modify the contents of a control in the cell surface)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell? = tableView.dequeueReusableCell(withIdentifier: "cell")
// Not the type of cell, if the queue will return nil, at this time requires create ⼀ cell
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
}
}
If it involves data processing, you can create a new NSMutableSet(), Used to store your operations (ordinary data is lost, stored in the didSelecetRow inside indexPath like) save anyway, a unique tag.
These are just solve the problem of multiplexing, to deal with discoloration, refer to the above solution.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if(indexPath.row >= postData2.count-5){
cell.backgroundColor = UIColor.red
}else{
cell.backgroundColor = UIColor.white /* Remaining cells */
}
return cell
}

Swift 3 button disappears from tableView cells

I'm trying to create a tableView that has (for now) only a button in each cell.
I hard coded the number of rows to be 100:
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 100
}
And this is my cellForRowAt function that creates the button and is suppose to properly place it in each cell:
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell")
let row = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let btn = UIButton(type:(UIButtonType.custom)) as UIButton
btn.backgroundColor = UIColor.black
btn.setTitle("(read more)", for: UIControlState.normal)
btn.titleLabel!.font = UIFont(name: "Helvetica", size: 10)
btn.frame = CGRect(x:300, y:row.bounds.height, width:70, height:20)
btn.addTarget(self, action: Selector(("buttonPressed:")), for: UIControlEvents.touchUpInside)
btn.tag = indexPath.row
cell.contentView.addSubview(btn)
return cell
}
So this places the buttons in each cell, but when I click on the cell, the associated button disappears or when i scroll down, most of the first few buttons are gone when I scroll back up. What am I doing wrong here? Any help would be greatly appreciated!
Thanks in advance.
This example maybe will help you:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet fileprivate weak var tableView: UITableView!
fileprivate let numberOfItems = 100
override func viewDidLoad() {
super.viewDidLoad()
tableView.contentInset.top = 44
}
#objc fileprivate func buttonPressed(sender: UIButton) {
print("tag: \(sender.tag)")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numberOfItems
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let accessory = UIButton(frame: CGRect(x: 0, y: 0, width: 70, height: 20))
accessory.backgroundColor = .black
accessory.setTitle("Read more", for: .normal)
accessory.titleLabel?.font = UIFont(name: "Helvetica", size: 12)
accessory.tag = indexPath.row
accessory.addTarget(self, action: #selector(buttonPressed(sender:)), for: .touchUpInside)
cell.accessoryView = accessory
return cell
}
}
you must create a cell everytime in cellForRowAt rather get the cell from dequeue and draw your content again. Creating a cell again and again is not an good idea. Finding own mistake and solving will another curve of learning.
l
et cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell") // should not do
let row = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) // can use it.
both line together should not use.

How do I clear all checks in UITableVIew when VC is returned to from another VC?

I have a scenario where a UITableView shows a list of players in a league.
The user selects two players to compare results. As a user selects a player a check is shown. Once the user has selected two users a new VC is presented, showing the results of the two players.
On this ResultsVC I have a back button which dismisses ResultsVC, and the view is returned to the originalVC.
Upon returning to this originalVC the checks next to the players which were selected for viewing are still visible.
How do I reset all checks when this VC is returned to?
This is my code for the original VC with the TableView:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PersonalStatsTableViewCell", for: indexPath as IndexPath) as! PersonalStatsTableViewCell
cell.textLabel?.text = self.communityPlayers[indexPath.row]
cell.textLabel?.font = UIFont(name: "Avenir", size: 12)
cell.textLabel?.textColor = UIColor.white // set to any colour
cell.layer.backgroundColor = UIColor.clear.cgColor
cell.personalStatsInfoButton.tag = indexPath.row
cell.personalStatsInfoButton.addTarget(self, action: #selector(infoClicked), for: UIControlEvents.touchUpInside)
cell.selectedBackgroundView?.backgroundColor = UIColor.red
return cell
}
func infoClicked(sender:UIButton){
let buttonRow = sender.tag
self.friendId = self.communityPlayerIds[buttonRow]
self.personalSelf = false
self.friendName = self.communityPlayers[buttonRow]
self.performSegue(withIdentifier: "personalStatsSegue", sender: self)
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.selectedCellTitle = self.communityPlayers[indexPath.row]
cellId = indexPath.row
//print (self.communityPlayerIds[indexPath.row])
if let cell = tableView.cellForRow(at: indexPath) {
if cell.isSelected {
cell.accessoryType = .checkmark
}
}
if let sr = tableView.indexPathsForSelectedRows {
print("didSelectRowAtIndexPath selected rows:\(sr)")
if sr.count == 2{
let tempId_1 = sr[0][1]
let tempId_2 = sr[1][1]
self.tempCount = 2
self.tempPlayerId_1 = self.communityPlayerIds[tempId_1]
self.tempPlayerId_2 = self.communityPlayerIds[tempId_2]
print ("you have selected player I'ds: ", self.tempPlayerId_1!, "and ", self.tempPlayerId_2!)
self.performSegue(withIdentifier: "showHeadToHeadSegue", sender: self)
}
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath as IndexPath) {
cell.accessoryType = .none
}
if let sr = tableView.indexPathsForSelectedRows {
print("didDeselectRowAtIndexPath selected rows:\(sr)")
}
}
}
I have read around the subject but nothing appears to work.
sussed it.
I added
cell.accessoryType = .none
into the func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell function
Then when the view is returned all checks are removed.

Resources