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

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

ただいまの
回答率

89.12%

swiftでLabelに文字送りアニメーションの実装

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,661

Honma

score 25

現在の状況(2017/6/29 11:00)

    required init?(coder aDecoder: NSCoder) {
//        super.init(coder: aDecoder)
        super.init(text: self.text, fontsize: CGFloat!, posX: CGFloat!, posY: CGFloat!, addView: SKScene!,
        nextLineKey: Character!, maxWidth: UInt!, delayTime: CGFloat!, mode: eTextState!, color: UIColor!){
            super.init(frame: .zero)

            if (nextLineKey != nil) { m_nextLineKey = nextLineKey }
            if (maxWidth != nil)    { self.maxWidth = maxWidth }
            if (delayTime != nil)   { self.m_delayTime = delayTime }
            if (mode != nil)        { self.m_state = mode }
            if (fontsize != nil)    { self.m_fontSize = fontsize }
            if (color != nil)       { self.m_color = color }


            self.m_posX = posX
            self.m_posY = posY
            self.m_parentScene = addView

            drawText(text: text)
        }
    }


目的:
init(coder:)の中から必要なイニシャライザを呼びたい
状況:
super.initの引数部分でCannot invoke '〜' with an argument list of type '〜'がでる
引数に問題があるようなのだが、解決できない


スマートフォン向けアプリ開発を下記の環境で行っています。
Swift3.0.1
Xcode8.3.3

http://neight968.hatenablog.com/entry/2015/07/22/040538
上記URLのソースコードをクラス化しLabelに実装したい

ソース

このほかに必要であれば追加します

TextEscapement1.swift※文字数制限のため一部コメントを削除しています

import SpriteKit
import UIKit

enum eTextState: Int {
    case send = 0
    case skip
    case remove
}

class TextEscapement1 : UILabel{

    // メンバ変数
    // テキストを文字送りするのに必要そうな変数
    var m_text: String?
    var m_count: Int = 0
    var m_strcount: CGFloat = 0.0
    var m_delayTime: CGFloat = 0.1
    var m_nextLineKey: Character = "嬲"
    var m_parentScene: SKScene?
    var m_fontSize: CGFloat = 12.0

    var m_labelArray: Array<SKLabelNode> = []

    // 文字の位置決定用変数(後で変換するのが面倒なのでCGCloatで作成)
    var x: UInt = 0
    var y: UInt = 0
    var maxWidth: UInt = 15
    var m_posX: CGFloat?
    var m_posY: CGFloat?
    var m_color: UIColor = UIColor.black
    var m_drawEndFlag: Bool = false

    var m_state: eTextState = .send {
        willSet{}
        didSet{
            switch m_state {
            case .send:
                self.m_delayTime = 0.1
            case .skip:
                self.skipDraw(text: m_text)
            case .remove:
                self.remove()
            }
        }
    }



    // (文字送りで表示するテキスト、フォントサイズ、初期位置X、初期位置Y、ラベルを取り付けるシーン)
    convenience init(text: String!, fontsize: CGFloat!, posX: CGFloat!, posY: CGFloat!, addView: SKScene!){
        self.init(text: text, fontsize: fontsize, posX: posX, posY: posY,addView: addView,nextLineKey: nil, maxWidth: nil, delayTime: nil, mode: nil, color: nil)
    }

    // (文字送りで表示するテキスト、フォントサイズ、初期位置X、初期位置Y、ラベルを取り付けるシーン、文字色)
    convenience init(text: String!, fontsize: CGFloat!, posX: CGFloat!, posY: CGFloat!, addView: SKScene!, color: UIColor!){
        self.init(text: text, fontsize: fontsize, posX: posX, posY: posY,addView: addView,nextLineKey: nil, maxWidth: nil, delayTime: nil, mode: nil, color: color)
    }
    // (文字送りで表示するテキスト、フォントサイズ、初期位置X、初期位置Y、ラベルを取り付けるシーン、横に書ける最大文字数)
    convenience init(text: String!, fontsize: CGFloat!, posX: CGFloat!, posY: CGFloat!, addView: SKScene!, maxWidth: UInt!){
        self.init(text: text, fontsize: fontsize, posX: posX, posY: posY,addView: addView,nextLineKey: nil, maxWidth: maxWidth, delayTime: nil, mode: nil, color: nil)
    }
    // (文字送りで表示するテキスト、フォントサイズ、初期位置X、初期位置Y、ラベルを取り付けるシーン、モード)
    convenience init(text: String!, fontsize: CGFloat!, posX: CGFloat!, posY: CGFloat!, addView: SKScene!, mode: eTextState){
        self.init(text: text, fontsize: fontsize, posX: posX, posY: posY,addView: addView,nextLineKey: nil, maxWidth: nil, delayTime: nil, mode: mode, color: nil)
    }
    // (文字送りで表示するテキスト、フォントサイズ、初期位置X、初期位置Y、ラベルを取り付けるシーン、文字表示の遅さ)
    convenience init(text: String!, fontsize: CGFloat!, posX: CGFloat!, posY: CGFloat!, addView: SKScene!, delayTime: CGFloat!){
        self.init(text: text, fontsize: fontsize, posX: posX, posY: posY,addView: addView,nextLineKey: nil, maxWidth: nil, delayTime: delayTime, mode: nil, color: nil)
    }

    init(text: String!, fontsize: CGFloat!, posX: CGFloat!, posY: CGFloat!, addView: SKScene!,
         nextLineKey: Character!, maxWidth: UInt!, delayTime: CGFloat!, mode: eTextState!, color: UIColor!){

        if (nextLineKey != nil) { m_nextLineKey = nextLineKey }
        if (maxWidth != nil)    { self.maxWidth = maxWidth }
        if (delayTime != nil)   { self.m_delayTime = delayTime }
        if (mode != nil)        { self.m_state = mode }
        if (fontsize != nil)    { self.m_fontSize = fontsize }
        if (color != nil)       { self.m_color = color }


        self.m_posX = posX
        self.m_posY = posY
        self.m_parentScene = addView

        drawText(text: text)  // **ここでエラーが発生**
    }

    required init? (coder aDecoder: NSCoder) {
        fatalError("init(coder: has not been implemented)")
    }

    /// テキストの描画
    private func drawText(text: String!){

        // テキストの保管と文字数の取得
        m_count = text.characters.count
        var text: String = text
        m_text = text

        if m_count == 0 { return }

        for n in 1 ... m_count {
            if m_state == .remove { return }

            let chara:Character = text.remove(at: text.startIndex)

            if chara == m_nextLineKey {
                y += 1
                x = 0
            } else if x > maxWidth {
                y += 1
                x = 0
            } else if m_posX! + (m_fontSize * CGFloat(x)) + m_fontSize/2.0 > (m_parentScene?.frame.width)! {
                y += 1
                x = 0
            }
            x += 1

            // ラベルノードの生成
            var label: SKLabelNode = SKLabelNode(text: "\(chara)")
            label.fontSize = m_fontSize
            label.position = CGPoint(x: m_posX! + (CGFloat(x-1) * m_fontSize), y: m_posY! - (CGFloat(y) * m_fontSize))
            label.alpha = 0.0
            label.fontColor = m_color

            // ラベルの取り付け
            m_parentScene?.addChild(label)
            // ラベルの配列に登録
            m_labelArray.append(label)

            // 表示する時間をずらすためのアクションの設定
            let delay = SKAction.wait(forDuration: TimeInterval(m_delayTime * m_strcount))
            let fadein = SKAction.fadeAlpha(by: 1.0, duration: 0.5)
            let seq = SKAction.sequence([delay, fadein])
            label.run(seq)


            m_strcount += 1.0
        }
        y = 0
        x = 0
        m_strcount = 0.0
    }

    /// スキップモードの文字の描画
    func skipDraw(text: String!){
        if m_drawEndFlag { return }

        self.remove()

        // テキストの保管と文字数の取得
        m_count = text.characters.count
        var text: String = text

        if m_count == 0 { return }

        for n in 1 ... m_count {
            if m_state == .remove { return }

            let chara:Character = text.remove(at: text.startIndex)

            if chara == m_nextLineKey {
                y += 1
                x = 0
            } else if x > maxWidth {
                y += 1
                x = 0
            } else if m_posX! + (m_fontSize * CGFloat(x)) + m_fontSize/2.0 > (m_parentScene?.frame.width)! {
                y += 1
                x = 0
            }
            x += 1

            // ラベルノードの生成
            var label: SKLabelNode = SKLabelNode(text: "\(chara)")
            label.fontSize = m_fontSize
            label.position = CGPoint(x: m_posX! + (CGFloat(x-1) * m_fontSize), y: m_posY! - (CGFloat(y) * m_fontSize))
            label.fontColor = m_color

            // ラベルの取り付け
            m_parentScene?.addChild(label)
            m_labelArray.append(label)
            m_strcount += 1.0
        }
        y = 0
        x = 0
        m_strcount = 0.0
    }


    /// 文字が全て表示されたかの確認
    func checkDrawEnd(){
        if m_labelArray.last?.alpha == 1.0 {
            m_drawEndFlag = true
        }
    }

    /// 描画モードの切り替え
    func changeState( mode: eTextState ){
        self.m_state = mode
    }

    /// 描画の基本設定はそのままに、違う文へ切り替え
    func changeText(text: String!){
        if m_drawEndFlag {
            self.remove()
            self.changeState( mode: .send )
            drawText(text: text)
        } else {
            self.changeState( mode: .skip )
        }
    }

    /// ラベルの取り外し
    func remove(){
        while m_labelArray.count > 0  {
            m_labelArray.last?.removeFromParent()
            m_labelArray.removeLast()
            m_drawEndFlag = false
        }
    }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

Storyboardからインスタンスを生成するときにinit(coder:)が呼ばれますので実装しないといけません。
NSObjectではなくUIViewを継承してみるとか(適当)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/06/29 13:04

    いえ、こちらこそ色々と試行錯誤してて中々返信できなくてすみません。
    ちょっと技術的に手に負えなくなってきたので方向転換も検討中です。
    ここまで丁寧に指導いただきありがとうございました!

    キャンセル

  • 2017/06/29 13:05

    上の書き込み、少し編集しましたので確認しておいて下さい。
    方向転換する方が良いと思います。あまり良い方向には進んでないように見えますので。

    キャンセル

  • 2017/06/29 13:07

    確認しました。ありがとうございます。

    キャンセル

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

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