I'm trying to pass the data and got this error: 'subscript(_:)' is unavailable: cannot subscript String with an Int, use a String.Index instead.
Here is my code:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: CustomLoopsCell = beatTableView.dequeueReusableCell(withIdentifier: "firstLoopCell", for: indexPath) as! CustomLoopsCell
let beatLoop = overtunePacks[indexPath.row]
// On the lines which is down I'm getting this error
let beatDesc = loopsDesc[indexPath.row]
let beatProd = loopsProd[indexPath.row]
let beatAudio = loopsAudio[indexPath.row]
let beatInst = loopsInst[indexPath.row]
cell.loopNameLabel.text = beatDesc
cell.producerLabel.text = beatProd
cell.instrumentLabel.text = beatInst
Here is the code from another view controller, from where I'm passing the data:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = storyboard?.instantiateViewController(identifier: "BeatViewID") as? BeatPackViewController
vc?.beatInfoCollectName = beatInfoCollect[indexPath.row].name
vc?.beatProducerName = beatInfoCollect[indexPath.row].producer
vc?.imageBeat = beatInfoCollect[indexPath.row].imagename
vc?.loopsAudio = beatAudioCollect[indexPath.row].loopPath
vc?.loopsDesc = beatAudioCollect[indexPath.row].name
vc?.loopsInst = beatAudioCollect[indexPath.row].instrument
vc?.loopsProd = beatAudioCollect[indexPath.row].producer
self.navigationController?.pushViewController(vc!, animated: true)
}
Here is my variables in second view controller, where I'm passing data:
var loopsAudio = ""
var loopsDesc = ""
var loopsInst = ""
var loopsProd = ""
Here is what I want to display:
struct BeatLoops: Decodable {
let name: String
let instrument: String
let loopPath: String
let producer: String
var songURL : URL {
let components = loopPath.components(separatedBy: ".")
guard components.count == 2,
let url = Bundle.main.url(forResource: components[0], withExtension: components[1]) else { fatalError("Audio file is missing") }
return url
}
}
I'm parsing this data and have instance: var beatAudioCollect = [BeatLoops]()
CodePudding user response:
Seems that you are trying to get Substring from a loopsDesc String here
let beatDesc = loopsDesc[indexPath.row]
...
let beatInst = loopsInst[indexPath.row]
The point is that you can't just get String's characters using subscription index.
If you want to get a character from a String, you should get it's Substring with a specified range.
Like that:
let index = loopsDesc.index(loopsDesc.startIndex, offsetBy: 1)
let mySubstring = loopsDesc[..<index]
Or another way:
1 - add this extension to a String:
extension StringProtocol {
subscript(offset: Int) -> Character {
self[index(startIndex, offsetBy: offset)]
}
}
2 - use it like that
let input = "My String Here"
let char = input[3]
//or
let char = String(input[3])
Please see another stackoverflow question related to that.
But it's unsafe method and I would suggest to use another way to get params (for example store them in Array, not in String)
CodePudding user response:
Your design is wrong.
Extracting single characters from a string in a table view to be displayed in different rows makes no sense.
Actually you are passing two objects to the second view controller, an infoCollect
object and an audioCollect
object.
First of all rather than extracting all properties just pass the entire objects.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = storyboard?.instantiateViewController(identifier: "BeatViewID") as! BeatPackViewController
vc.infoCollect = beatInfoCollect[indexPath.row]
vc.audioCollect = beatAudioCollect[indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
}
By the way using multiple arrays as data source is strongly discouraged!.
In the second controller replace the String
properties with
var infoCollect : Loop!
var audioCollect : BeatLoops!
If the structs are declared inside in first view controller you have to write
var infoCollect : BPLibraryViewController.Loop!
var audioCollect : BPLibraryViewController.BeatLoops!
Then remove the table view and add UILabel
s instead. In viewDidLoad
assign the values for example
imageBeatLabel.text = infoCollect.name
loopsAudioLabel.text = audioCollect.loopPath