Как заменить первые два слова в строке?
- Есть два котроллера (FirstVC и SecondVC);
- На обоих котроллерах таблица;
- Данные в ячейки первой таблицы вносятся из третьего контроллера, где располагается соответствующие textFieldы. Данные в ячейках второй таблицы не важны (добавил просто для примера).
- Над второй таблицей (которая на SecondVC) есть UIView, в котором два UILabel. Первый UILabel статичный (там просто слово «СПИСОК»), его значение меняться не будет. Второй UILabel (прямо под первым) – динамичный. Там заданный текст с интерполяцей строк (string interpolation) – “участников (adjustedEventNameText)”
- Сам adjustedEventNameText задан для того, чтобы выводить названия ячеек из первого контроллера в tableHeaderView на втором контроллере с правильными склонениями на русском языке. К примеру «Соревнование по легкой атлетике» должно преобразовываться в «соревнованиЯ по легкой атлетике». Эта интерполяция во втором стринге идет сразу после слова «участников» и, таким образом, финально получается «СПИСОК участников соревнования по легкой атлетике».
Кстати, если кто-то знает более удачный способ как обходить склонения и окончания, предлагайте пожалуйста, иначе код очень захламлен.
Единичные первые слова я нашел как склонять. А вот когда идет заданное словосочетание, типа «Благотворительное соревнование», я не знаю, как обрабатывать сразу два слова в начале стринга. Помогите пожалуйста.
Вот код второго котроллера:
import UIKit
class SecondVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var names: [Cell2Model] = []
var textForChanging: String = ""
var switchedFirstWord: String {
switch textForChanging.firstWord {
case "Соревнование": return "соревнования"
default: return "none" } }
var restoOfTheName: String {
var string = textForChanging
string.enumerateSubstrings(in: string.startIndex..., options: .byWords) { (_, _, enclosingRange, stop) in
string.removeSubrange(enclosingRange)
stop = true }
return string }
var adjustedEventNameText: String {
return switchedFirstWord + " " + restoOfTheName }
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
// names будут браться из UITextField на четвертом контроллере
names = [
(Cell2Model(name: "Иванов")),
(Cell2Model(name: "Петров")),
(Cell2Model(name: "Сидоров")) ]
let tableHeader = UIView()
tableView.tableHeaderView = tableHeader
let labelOne = UILabel(frame: tableHeader.bounds)
labelOne.text = "СПИСОК"
labelOne.font = UIFont(name:"Arial-BoldMT", size: 17.0)
labelOne.numberOfLines = 0
labelOne.lineBreakMode = .byWordWrapping
labelOne.textAlignment = .center
labelOne.translatesAutoresizingMaskIntoConstraints = false
let labelTwo = UILabel(frame: tableHeader.bounds)
labelTwo.translatesAutoresizingMaskIntoConstraints = false
labelTwo.text = "участников \(adjustedEventNameText)"
labelTwo.font = UIFont(name:"Arial-BoldMT", size: 17.0)
labelTwo.numberOfLines = 0
labelTwo.lineBreakMode = .byWordWrapping
labelTwo.textAlignment = .center
labelTwo.translatesAutoresizingMaskIntoConstraints = false
tableHeader.addSubview(labelOne)
tableHeader.addSubview(labelTwo)
let g = tableHeader.layoutMarginsGuide
NSLayoutConstraint.activate([
labelOne.topAnchor.constraint(equalTo: g.topAnchor, constant: 11.0),
labelOne.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
labelOne.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
labelTwo.topAnchor.constraint(equalTo: labelOne.bottomAnchor, constant: 0.0),
labelTwo.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
labelTwo.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0), ])
let c = labelTwo.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -11.0)
c.priority = .required - 1
c.isActive = true
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let tableHeader = tableView.tableHeaderView {
let fitSize: CGSize = CGSize(width: tableView.frame.width, height: .greatestFiniteMagnitude)
let sz: CGSize = tableHeader.systemLayoutSizeFitting(fitSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .defaultLow)
let height: CGFloat = sz.height
var headerFrame = tableHeader.frame
if height != headerFrame.size.height {
headerFrame.size.height = height
tableHeader.frame = headerFrame
tableView.tableHeaderView = tableHeader } } }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "secondCell", for: indexPath) as! SecondCell
let Name = names[indexPath.row]
cell.label.text = Name.name
return cell } }
extension StringProtocol {
var byWords: [SubSequence] { components(separated: .byWords) }
func components(separated options: String.EnumerationOptions)-> [SubSequence] {
var components: [SubSequence] = []
enumerateSubstrings(in: startIndex..., options: options) { _, range, _, _ in components.append(self[range]) }
return components }
var firstWord: SubSequence? {
var word: SubSequence?
enumerateSubstrings(in: startIndex..., options: .byWords) { _, range, _, stop in
word = self[range]
stop = true }
return word } }
А также, для целостного понимания, код первого контроллера:
import UIKit
class FirstVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
var names: [Cell1Model] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
// names будут браться из UITextField на третьем контроллере
names = [
Cell1Model(name: "Соревнование по легкой атлетике"),
Cell1Model(name: "Благотворительное соревнование по легкой атлетике")
]
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
if let vc = storyboard?.instantiateViewController(withIdentifier: "SecondVC") as? SecondVC {
vc.textForChanging = names[indexPath.row].name!
self.navigationController?.pushViewController(vc, animated: true) } }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! Cell
let Name = names[indexPath.row]
cell.label.text = Name.name
return cell }
}