Probleme mit Arrays und einem Image Slider

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Probleme mit Arrays und einem Image Slider

    Hi, Ich bin neu hier und auch neu bei Swift bzw. Xcode.

    Hier zu meiner Frage:
    Diesen ImageSlider habe ich in meiner App implementiert: youtube.com/watch?v=n9NhtI2XlGM
    Er funktioniert wunderbar. Jetzt möchte ich diesen aber noch erweitern.

    Dazu brauche in ein weiteres Array, somit sind es zwei. "imgArr" speichert weiterhin (wie im Original) die Dateinamen der Bilder. Neu hinzugekommen ist "welcheNote". Dieses Array soll nur einen Buchstaben speichern wie "E" or "F".

    Jetzt möchte ich wenn das erste Bild angezeigt wird (imgArr[1]), den Text von welcheNote[1] zusätzlich anzeigen lassen. Bei imgArr[2] soll demzufolge welcheNote[2] angezeigt werden usw.

    Was nun nicht klappt ist herauszubekommen welches Bild gerade angezeigt wird. Ich suche als das x in imgArr[x].

    Bisher probiert habe ich das so: note.text = welcheNote[indexPath.row] innerhalb func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {} -> siehe Code unten.

    indexPath[row] liefert allerdings merkwürdige Werte. Am Anfang ist es 0, was ja auch stimmt, aber schon beim ersten Swipe wird indexPath[row] direkt 2, sollte aber natürlich 1 sein.

    EDIT: Vielleicht sollte ich noch dazusagen, dass die Bilder in einem UIImageView in einer UICollectionViewCell angezeigt werden (im Storyboard eingerichtet) . Es gibt noch eine weitere Datei mit dem Namen "DataCollectionViewCell.swift" und dem Inhalt:
    import UIKit
    class DataCollectionViewCell: UICollectionViewCell {
    @IBOutlet weak var img: UIImageView!
    }

    Ich denke, dass dies keine wichtige info ist und dass das Problem im unten angezeigten Code liegt.

    Ich habe schon Stunden damit verbracht und komme aber auf keinen grünen Zweig. Kann mit jemand helfen?



    Hier der Code:

    import UIKit
    import AVFoundation
    class Altissimo: UIViewController {
    var imgArr = [UIImage(named: "altissimoE"),
    UIImage(named: "altissimoF"),
    UIImage(named: "altissimoFis"),
    UIImage(named: "altissimoFis2"),
    UIImage(named: "altissimoG"),
    UIImage(named: "altissimoGis"),
    UIImage(named: "altissimoA"),
    UIImage(named: "altissimoBb"),
    UIImage(named: "altissimoB"),
    UIImage(named: "altissimoC"),
    UIImage(named: "altissimoCis"),
    UIImage(named: "altissimoD"),
    UIImage(named: "altissimoEb"),
    UIImage(named: "altissimoEhigh"),
    UIImage(named: "altissimoFhigh")
    ]
    var welcheNote = ["E", "F", "F#", "G", "G#", "A", "Bb", "B", "C", "C#", "D", "Eb", "E", "F"]
    let avPlayer = AVPlayer()
    var pathToDrone: String = "A440HzOrgel"
    @IBOutlet weak var colltionView: UICollectionView!
    @IBOutlet weak var note: UILabel!
    @IBOutlet weak var playButtonFingerings: UIButton!
    @IBAction func playButtonActionFingerings(_ sender: UIButton) {
    if playButtonFingerings.currentBackgroundImage == UIImage(named: "play") {
    playButtonFingerings.setBackgroundImage(UIImage(named: "pause"), for: .normal)
    let path = Bundle.main.path(
    forResource: pathToDrone, ofType: "mp3")!
    let url = URL(fileURLWithPath: path)
    let ava = AVAsset(url: url)
    let avItem = AVPlayerItem(asset: ava)
    avPlayer.replaceCurrentItem(with: avItem)
    avPlayer.play()
    } else {
    playButtonFingerings.setBackgroundImage(UIImage(named: "play"), for: .normal)
    avPlayer.pause()
    }
    }
    override func viewDidLoad() {
    super.viewDidLoad()
    }
    extension Altissimo: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return imgArr.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    print(indexPath.row)
    note.text = welcheNote[indexPath.row]
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? DataCollectionViewCell
    cell?.img.image = imgArr[indexPath.row]
    return cell!
    }
    }
    extension Altissimo: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let size = UIScreen.main.bounds
    return CGSize(width: size.width, height: size.height)
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 0
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0
    }
    }

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von lololarumpel ()

  • Danke für deine Hilfe.

    Ich füge also diesen Code in
    class Altissimo: UIViewController {} ein?

    Momentan habe ich dein Code unterhalb viewDidLoad eingefügt.
    Ich bekomme merkwürdigerweise aber immer nur "A" in note.text angezeigt. EDIT: ich weiß auch warum: Das ist der Text, der ohnehin schon vom Storyboard für das Label erzeugt wird.
    Der Text wird somit nicht notiert. Wahrscheinlich weil die Funktion nicht aufgerufen wird.

    Wie und wo mache ich das?

    Quellcode

    1. import UIKit
    2. import AVFoundation
    3. class Altissimo: UIViewController {
    4. var imgArr = [UIImage(named: "altissimoE"),
    5. UIImage(named: "altissimoF"),
    6. UIImage(named: "altissimoFis"),
    7. UIImage(named: "altissimoFis2"),
    8. UIImage(named: "altissimoG"),
    9. UIImage(named: "altissimoGis"),
    10. UIImage(named: "altissimoA"),
    11. UIImage(named: "altissimoBb"),
    12. UIImage(named: "altissimoB"),
    13. UIImage(named: "altissimoC"),
    14. UIImage(named: "altissimoCis"),
    15. UIImage(named: "altissimoD"),
    16. UIImage(named: "altissimoEb"),
    17. UIImage(named: "altissimoEhigh"),
    18. UIImage(named: "altissimoFhigh")
    19. ]
    20. var welcheNote = ["E", "F", "F#", "G", "G#", "A", "Bb", "B", "C", "C#", "D", "Eb", "E", "F"]
    21. let avPlayer = AVPlayer()
    22. var pathToDrone: String = "A440HzOrgan"
    23. @IBOutlet weak var colltionView: UICollectionView!
    24. @IBOutlet weak var note: UILabel!
    25. @IBOutlet weak var playButtonFingerings: UIButton!
    26. // MARK: Tap auf Play Button
    27. @IBAction func playButtonActionFingerings(_ sender: UIButton) {
    28. if playButtonFingerings.currentBackgroundImage == UIImage(named: "play") {
    29. playButtonFingerings.setBackgroundImage(UIImage(named: "pause"), for: .normal)
    30. let path = Bundle.main.path(
    31. forResource: pathToDrone, ofType: "mp3")!
    32. let url = URL(fileURLWithPath: path)
    33. let ava = AVAsset(url: url)
    34. let avItem = AVPlayerItem(asset: ava)
    35. avPlayer.replaceCurrentItem(with: avItem)
    36. avPlayer.play()
    37. } else {
    38. playButtonFingerings.setBackgroundImage(UIImage(named: "play"), for: .normal)
    39. avPlayer.pause()
    40. }
    41. }
    42. override func viewDidLoad() {
    43. super.viewDidLoad()
    44. // self.view.backgroundColor = UIColor(red: 0, green: 1, blue: 0, alpha: 1)
    45. // self.navigationItem.titleView = UIImageView(image: UIImage(named: "saxophone"))
    46. // self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: nil, action: nil)
    47. }
    48. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){
    49. print(indexPath.row)
    50. print(welcheNote[indexPath.row])
    51. note.text = welcheNote[indexPath.row]
    52. }
    53. // MARK: Shake to play sound
    54. override func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
    55. playButtonFingerings.setBackgroundImage(UIImage(named: "pause"), for: .normal)
    56. let path = Bundle.main.path(
    57. forResource: pathToDrone, ofType: "mp3")!
    58. let url = URL(fileURLWithPath: path)
    59. let ava = AVAsset(url: url)
    60. let avItem = AVPlayerItem(asset: ava)
    61. avPlayer.replaceCurrentItem(with: avItem)
    62. avPlayer.play()
    63. }
    64. // override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
    65. // playButtonFingerings.setBackgroundImage(UIImage(named: "play"), for: .normal)
    66. // avPlayer.pause()
    67. // }
    68. }
    69. extension Altissimo: UICollectionViewDelegate, UICollectionViewDataSource {
    70. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    71. return imgArr.count
    72. }
    73. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    74. let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? DataCollectionViewCell
    75. cell?.img.image = imgArr[indexPath.row]
    76. return cell!
    77. }
    78. }
    79. extension Altissimo: UICollectionViewDelegateFlowLayout {
    80. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    81. let size = UIScreen.main.bounds
    82. return CGSize(width: size.width, height: size.height)
    83. }
    84. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    85. return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    86. }
    87. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    88. return 0
    89. }
    90. func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    91. return 0
    92. }
    93. }
    Alles anzeigen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von lololarumpel ()

  • Ok cool. Durch Zufall habe ich jetzt festgestellt daß dein Code funktioniert . Wenn ich nämlich in das Bild im Simulator klicke schreibt er in "note.text" den korrekten String rein.
    Wahrscheinlich ist der Code einfach falsch platziert, denn der Text soll ja ohne Tap bzw. Klick kommen sondern direkt beim Swipe kommen.

    Ich bin jetzt schon weiter aber funktionieren tut es noch nicht ganz wie es soll.
  • lololarumpel schrieb:

    Ich füge also diesen Code in
    class Altissimo: UIViewController {} ein?
    Die Methode gehört doch zu einem Protokoll, oder nicht? Guck dir mal die Doku an, guck dir mal deinen Code bzw. Swift Protocols.

    lololarumpel schrieb:

    Ok cool. Durch Zufall habe ich jetzt festgestellt daß dein Code funktioniert . Wenn ich nämlich in das Bild im Simulator klicke schreibt er in "note.text" den korrekten String rein.
    Das von mir war doch nur geraten... und funktioniert anscheinend wie erwartet. Siehe Dokumentation

    lololarumpel schrieb:

    Wahrscheinlich ist der Code einfach falsch platziert, denn der Text soll ja ohne Tap bzw. Klick kommen sondern direkt beim Swipe kommen.
    Mein Vorschlag war falsch. Schau mal ob da etwas anderes vom Protokoll passen könnte (highlighted, focused). Ansonsten geht das irgendwie anders.
  • Ich habe tatsächlich was gefunden und habe momentan beide Methoden drin:

    C-Quellcode

    1. // Bei Tap wird neue Note angezeigt
    2. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    3. note.text = welcheNote[indexPath.row]
    4. }
    5. // Bei Swipe wird neue Note angezeigt
    6. func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    7. print(indexPath.row)
    8. note.text = welcheNote[indexPath.row]
    9. }
    Ist im Prinzip okay aber in folgendem Szenario steht leider doch der falsche Text da:
    1- wenn man das Bild wechseln möchte und man also nach links swipe (selbst wenn es nur ein Pixel ist)
    2- aber nicht komplett swiped, also das Bild wechselt nicht
    3- steht leider schon der Text vom nächsten Bild da

    Am besten wäre es wenn der Text des neuen Bildes erst dann dasteht wenn es auch komplett sichtbar ist.
  • lololarumpel schrieb:

    Ist im Prinzip okay aber in folgendem Szenario steht leider doch der falsche Text da:
    1- wenn man das Bild wechseln möchte und man also nach links swipe (selbst wenn es nur ein Pixel ist)
    2- aber nicht komplett swiped, also das Bild wechselt nicht
    3- steht leider schon der Text vom nächsten Bild da
    Ich weiss nicht, ob Dir das hilft, aber ich habe bei einem UIPageViewController ein ähnliches Problem gehabt. Ich habe die folgende Delegate-Methode benutzt, um über den Parameter completed abzufragen, ob das Swipen "vollständig" war:

    Quellcode

    1. - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed

    Vielleicht kennt eine UICollectionView ja auch eine derartige Methode...?

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Hallo!

    lololarumpel schrieb:

    Ich habe tatsächlich was gefunden und habe momentan beide Methoden drin:

    C-Quellcode

    1. // Bei Tap wird neue Note angezeigt
    2. func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    3. note.text = welcheNote[indexPath.row]
    4. }
    5. // Bei Swipe wird neue Note angezeigt
    6. func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    7. print(indexPath.row)
    8. note.text = welcheNote[indexPath.row]
    9. }
    Ist im Prinzip okay aber in folgendem Szenario steht leider doch der falsche Text da:
    1- wenn man das Bild wechseln möchte und man also nach links swipe (selbst wenn es nur ein Pixel ist)
    2- aber nicht komplett swiped, also das Bild wechselt nicht
    3- steht leider schon der Text vom nächsten Bild da

    Am besten wäre es wenn der Text des neuen Bildes erst dann dasteht wenn es auch komplett sichtbar ist.
    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath)

    Methoden mit will im Namen erfolgen gewolltermaßen vor der eigentlichen Änderung.
    Daher ist es für mich verständlich, dass es nicht funktioniert wie gewünscht.

    Meist gibt es dann ein Gegenstück mit did im Namen, dass über die vollzogene Änderung informiert.
    Das ist in UICollectionViewDelegate offenbar nicht vorhanden.

    Versuche, es mal mit collectionView(_:didUpdateFocusIn:with:) zu lösen. Die Beschreibung legt
    nahe, dass es das gewünschte Verhalten aufweist.

    Grüße
    Marco