質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.92%

アニメーション中にボタンをタップしたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 918

aaaaaachannel

score 37

何度も同じ質問をしてすいません。質問の仕方も下手くそですいません。
アニメーションさせたボタンがアニメーション中にボタンをタップしたいのですが、できません。

  // viewをタップされた時の処理
  @objc func viewTap(sender: UITapGestureRecognizer){
    print("GAMEOVER")

  }


最初、UIRecognizerを使おうと思い、このようにしたところviewはタップするとGAMEOVERと表示されます。しかしどうやってボタンと識別すればいいのかがわかりません。

次に、presentationlayerを使おうと考えました。以下のサイトを参考にしましたが、これも viewの例でuibuttonへの適用がわかりませんでした。また、ボタンではない、viewはpresentationlayerがなくても反応しているのでちょっと違うのかなと思いました。

(https://ja.stackoverflow.com/questions/31506/アニメーション中のビューをタップしてイベント処理?rq=1)

やりたいことをまとめると、
1アニメーションで流れる画面でタップした場所がボタンかボタン以外の画面かを判定する
2ボタンの場合、正しくボタンを押したのかボタンのタグで判定する
ということです。

以下、コードの全文を貼ります。

import UIKit
import AVFoundation

let urls: [String] = ["1:2","3:4","5:6:7", "8","9","10","11","12","13:14:15","1:2","3:4","5:6:7", "8","9","10","11","12","13:14:15"]



class ViewController: UIViewController{


  let largeImageView = UIImageView()
  var imageHeight:CGFloat!

  //makenote
  var note:UIButton!

  var duration:Double!
  var durations:[Double] = []

  var heights:[CGFloat] = []
  var sum:CGFloat = 0

  var number:CGFloat! = 0
  var differenceNumber:CGFloat! = 0
  var intNumber:Int! = 0

  var needHeights:[Int] = []
  var needsum:Int!

  var withduration:CGFloat!
  var notes:[UIButton] = []
  var tags:[Int] = []

  //music
  var audioPlayer :AVAudioPlayer! = nil



  override func viewDidLoad() {

    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib
    view.isUserInteractionEnabled = true
    largeImageView.isUserInteractionEnabled = true
    makeSound()
    setBackGround()
    makeLine()







  }

  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    Timer.scheduledTimer(withTimeInterval: 0.016, repeats: true) { (timer) in
      self.largeImageView.center.y += 1.0
      if self.largeImageView.center.y >= self.view.bounds.size.width {
        timer.invalidate()
      }
    }
  }


  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }

  @objc func tap(_ gestureRecognizer: UIGestureRecognizer) {
    let point = gestureRecognizer.location(in: view)
    if let presentation = largeImageView.layer.presentation(),
      let _ = presentation.hitTest(point) {
      print("G")
      note?.sendActions(for: .touchUpInside)



    }
  }


//  // viewをタップされた時の処理
//  @objc func viewTap(sender: UITapGestureRecognizer){
//    print("GAMEOVER")
//
//
//  }
//

  func setBackGround(){
    //背景

    //neednumber
    for url in urls {
      let soundFilePath:NSString = Bundle.main.path(forResource:url, ofType: "mp3")! as NSString
      let sound :URL = URL(fileURLWithPath: soundFilePath as String)
      do {
        let audioFile: AVAudioFile = try AVAudioFile(forReading: sound)
        let sampleRate = audioFile.fileFormat.sampleRate
        duration = Double(audioFile.length) / sampleRate
        //all fine with jsonData here
      } catch {
        //handle error
        print(error)
      }

      if 0 < duration && duration < 1.5{
        //1
        let one = 50
        needHeights.append(one)

      }
      else if 1.5 < duration && duration < 2.5{
        //2
        let two = 100
        needHeights.append(two)


      }
      else if 2.5 < duration && duration < 3.5{
        //3
        let three = 150
        needHeights.append(three)
      }
    needsum = needHeights.reduce(0){ $0 + $1 }
    print("needsum")
    print(needsum)

    }

    number = CGFloat(needsum)/self.view.frame.height
    print(number)



    //画像
    var imageViewArray:Array<UIImageView> = []
    let img = UIImage(named: "background")
    let imageView = UIImageView(image:img)
    imageHeight = imageView.bounds.height*number

    largeImageView.frame = CGRect(x: 0, y:-imageHeight,width:self.view.frame.width,height:imageHeight)


    print(largeImageView.frame)
    print(imageView.frame.height)
    print(imageView.bounds.height)


    for i in 0..<Int(number){
      let imageView = UIImageView(image:img)
      imageView.frame = CGRect(x: 0, y: CGFloat(i) * imageView.bounds.height,width:self.view.frame.width,height:imageView.bounds.height)
      self.view.sendSubview(toBack: imageView)
      largeImageView.addSubview(imageView)
      imageViewArray.append(imageView)
      print(imageView.frame)
      print(CGFloat(i) * imageView.bounds.height)

    }

    view.addSubview(largeImageView)

    //makenote

    for (index,url) in urls.enumerated() {
      let soundFilePath:NSString = Bundle.main.path(forResource:url, ofType: "mp3")! as NSString
      let sound :URL = URL(fileURLWithPath: soundFilePath as String)
      do {
        let audioFile: AVAudioFile = try AVAudioFile(forReading: sound)
        let sampleRate = audioFile.fileFormat.sampleRate
        duration = Double(audioFile.length) / sampleRate
        durations.append(duration)
        //all fine with jsonData here
      } catch {
        //handle error
        print(error)
      }


      let width = self.view.frame.width

      intNumber = Int(number)
      differenceNumber = number-CGFloat(intNumber)

      let note = UIButton()

      if 0 < duration && duration < 1.5{
        //1
        print(sum)

        let randNum = arc4random_uniform(4)
        note.frame = CGRect(x:CGFloat(randNum) * width/4.0,y:0+imageHeight-imageView.frame.height*differenceNumber-sum,width:width/4.0,height:50)
        heights.append(note.frame.height)
        sum = heights.reduce(0){ $0 + $1 }
        note.frame = CGRect(x:CGFloat(randNum) * width/4.0,y:0+imageHeight-imageView.frame.height*differenceNumber-sum,width:width/4.0,height:50)

         print(sum)
      }
      else if 1.5 < duration && duration < 2.5{
        //2
        print(sum)

        let randNum = arc4random_uniform(4)
        note.frame = CGRect(x:CGFloat(randNum) * width/4.0,y:0+imageHeight-imageView.frame.height*differenceNumber-sum,width:width/4.0,height:100)
        heights.append(note.frame.height)
        sum = heights.reduce(0){ $0 + $1 }
        note.frame = CGRect(x:CGFloat(randNum) * width/4.0,y:0+imageHeight-imageView.frame.height*differenceNumber-sum,width:width/4.0,height:100)

         print(sum)

      }
      else if 2.5 < duration && duration < 3.5{
        //3

        print(sum)

        let randNum = arc4random_uniform(4)
        note.frame = CGRect(x:CGFloat(randNum) * width/4.0,y:0+imageHeight-imageView.frame.height*differenceNumber-sum,width:width/4.0,height:150)
        heights.append(note.frame.height)
        sum = heights.reduce(0){ $0 + $1 }
        note.frame = CGRect(x:CGFloat(randNum) * width/4.0,y:0+imageHeight-imageView.frame.height*differenceNumber-sum,width:width/4.0,height:150)

         print(sum)

      }


      note.backgroundColor = UIColor.black
      note.layer.borderColor = UIColor.white.cgColor
      note.layer.borderWidth = 1.0
      note.tag = index

      tags.append(note.tag)
      notes.append(note)

      note.addTarget(self, action: #selector(ViewController.buttonTapped(sender:)), for: .touchUpInside)
      largeImageView.addSubview(note)



    }

    print(tags)


    //seconds
    let notePerSecond = 1
    let noteNumber = sum/50.0
    withduration = CGFloat(notePerSecond) * noteNumber

    // アニメーション処理
    UIView.animate(withDuration: TimeInterval(withduration), delay: 0, options: [.transitionCrossDissolve,.allowUserInteraction], animations: {
      self.largeImageView.frame = CGRect(x: 0, y: 0,width:self.view.frame.width,height:self.imageHeight)

    }) { _ in

    }




    //layerpresentation
    let _selector = #selector(tap(_:))
    let gesture = UITapGestureRecognizer(target: self, action: _selector)
    view.addGestureRecognizer(gesture)

}

  func makeLine(){
  //中略(線を引く処理)

  }



  func makeSound(){

    let soundFilePath:NSString = Bundle.main.path(forResource: "Pathetique", ofType: "mp3")! as NSString
    let sound :NSURL = NSURL(fileURLWithPath: soundFilePath as String)
    do{
      audioPlayer = try AVAudioPlayer(contentsOf:sound as URL, fileTypeHint:nil)
    }catch{
      print("error")
    }
    audioPlayer.prepareToPlay()

  }
  @objc func buttonTapped(sender:Any){
    var tag2:Int!
    let tappedNote = sender as AnyObject
    let tag = tappedNote.tag
    UIApplication.shared.beginIgnoringInteractionEvents()

    if tag == 0{
      audioPlayer.currentTime = 0.0
      self.audioPlayer.play()


      DispatchQueue.main.asyncAfter(deadline: .now() + durations[0]) {
        self.audioPlayer.pause()
        UserDefaults.standard.set(tag, forKey: "integerKeyName")
      }

    }else{
      tag2 = UserDefaults.standard.integer(forKey: "integerKeyName")
      if tag ==  tag2 + 1{

        let rangeArray = durations.prefix(tag!)
        let minutes = rangeArray.reduce(0) { $0 + $1 }
        audioPlayer.currentTime = minutes
        self.audioPlayer.play()
        UserDefaults.standard.set(tag, forKey: "integerKeyName")


        let pauseTime = durations[tag!]
        DispatchQueue.main.asyncAfter(deadline: .now() + pauseTime) {
          self.audioPlayer.pause()

          print(pauseTime)

        }

      }else{
        print("ミス!")
      }
    }

  }






}

めんどくさくてすいません。よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

「UIViewなら出来る」のでしたら、UIButtonをやめてUIViewやUILabelなどにしてはどうでしょうか?
(UIButtonを使う必要は無さそうなので)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る