0

I'm getting a misalignment of a UILabel (variable name: wrongCountLabel) in a UITableView section header, as it's programatically set to a fixed x and y coordinate. These coordinates work fine for smaller screens but fall short of the right hand side on larger screens (see screen dumps below).

enter image description here

Since I created the section header in code I've tried to programatically anchor the trailing edge of the "Wrong (times)" label to the trailing edge of UITableView. When I run the widget, it says it's unable to load the data.

//
//  TodayViewController.swift
//  Widget
//
//  Created by on 10/02/2019.
//  Copyright © 2019. All rights reserved.
//

import UIKit
import NotificationCenter

class TodayViewController: UIViewController, NCWidgetProviding, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!

    var words = [String]()
    var sortedPracticeWords = [String]()
    var chosenLanguage = String()
    let wordsString = "Words"

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view from its nib.
        if let defaults = UserDefaults(suiteName: "group.co.uk.tirnaelectronics.polyglot") {
            if let savedLanguage = defaults.object(forKey: "languageChosen") as? String {
                print("savedLanguage is: \(savedLanguage)")
                chosenLanguage = savedLanguage
                if let savedWords = defaults.object(forKey: "\(chosenLanguage)\(wordsString)") as? [String] {
                    words = savedWords
                }
            }
        }
        extensionContext?.widgetLargestAvailableDisplayMode = .expanded

        sortPracticeWords()
    }

    func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
        if activeDisplayMode == .compact {
            preferredContentSize = CGSize(width: 0, height: 110)
        } else {
            preferredContentSize = CGSize(width: 0, height: 440)
        }
    }

    func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) {
        // Perform any setup necessary in order to update the view.

        // If an error is encountered, use NCUpdateResult.Failed
        // If there's no update required, use NCUpdateResult.NoData
        // If there's an update, use NCUpdateResult.NewData

        completionHandler(NCUpdateResult.newData)
    }

    func sortPracticeWords() {
        var practiceWords = [String]()

        for i in 1..<words.count {
            if Int(words[i - 1].components(separatedBy: "::")[2]) ?? 0 > 0 {
                practiceWords.append(words[i - 1])
            }
        }
        var sortedAboveIndex = practiceWords.count
        var swaps = 0
        var tempPracticeWord = String()

        repeat {
            var lastSwapIndex = 0

            for i in 1..<sortedAboveIndex {
                if Int(practiceWords[i - 1].components(separatedBy: "::")[2])! < Int(practiceWords[i].components(separatedBy: "::")[2])! {
                    tempPracticeWord = practiceWords[i]
                    practiceWords[i] = practiceWords[i - 1]
                    practiceWords[i - 1] = tempPracticeWord
                    lastSwapIndex = i
                    swaps += 1
                }
            }
            sortedAboveIndex = lastSwapIndex
        } while (sortedAboveIndex != 0)
        sortedPracticeWords = practiceWords
        print("sortedPracticeWords are: \(sortedPracticeWords)")
        print("practiceWords is sorted in \(swaps) swaps.")
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sortedPracticeWords.count
    }

    internal func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = UIView()
        view.backgroundColor = UIColor(white: 1, alpha: 0.2)

        let languageLabel = UILabel()
        languageLabel.text = "\(chosenLanguage.capitalized)"
        languageLabel.frame = CGRect(x: 10, y: 5, width: 170, height: 20)
        //languageLabel.leadingAnchor.constraint(equalTo: tableView.layoutMarginsGuide.leadingAnchor).isActive = true
        view.addSubview(languageLabel)
        let wrongCountLabel = UILabel()
        wrongCountLabel.text = "Wrong (times)"
        wrongCountLabel.textAlignment = .left
        wrongCountLabel.frame = CGRect(x: 180, y: 5, width: 120, height: 20)
        //wrongCountLabel.trailingAnchor.constraint(equalTo: tableView.layoutMarginsGuide.trailingAnchor).isActive = true
        view.addSubview(wrongCountLabel)

        return view
    }

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 30
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell:TodayCustomCell = self.tableView.dequeueReusableCell(withIdentifier: "PracticeWord") as! TodayCustomCell

        let sortedPracticeWord = sortedPracticeWords[indexPath.row]
        print("practiceWord is: \(sortedPracticeWord)")

        let split = sortedPracticeWord.components(separatedBy: "::")

        cell.practiceWord.textColor = UIColor(white: 1, alpha: 0.75)

        cell.selectedBackgroundView = UIView()
        cell.selectedBackgroundView!.backgroundColor = UIColor(white: 1, alpha: 0.20)

        cell.practiceWord.frame = CGRect(origin: CGPoint(x: 10, y: 10), size: CGSize(width: 200, height: 40))
        cell.wrongCount.frame = CGRect(origin: CGPoint(x: 210, y: 10), size: CGSize(width: 100, height: 40))

        cell.practiceWord?.text = split[1]
        cell.wrongCount?.text = split[2]

        print("cell is: \(cell)")
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)

        /*if let cell = tableView.cellForRow(at: indexPath) {
            let practiceWord = sortedPracticeWords[indexPath.row]
            let split = practiceWord.components(separatedBy: "::")
            cell.detailTextLabel?.text = split[2]
            print("Detail cell is: \(cell)")
        }*/
    }
}

The right hand screen should display like the left hand screen, only on a bigger screen.

I need some code that anchors UILabels so they work regardless of user's screen size.

Tirna
  • 383
  • 1
  • 12

1 Answers1

0

Would changing:

wrongCountLabel.textAlignment = .left

To

wrongCountLabel.textAlignment = .right

Help?

  • No, nor does .center or .justified. It needs to be anchored to the far right relative to the UITableView object, so it can adjust accordingly to the screen size. I've not seen an explanation of this in any of my searches. – Tirna Apr 06 '19 at 15:26