2017-09-15 5 views
1

私は、画面にアクティビティや情報を表示するために、アプリケーションにコンソールを作成したいと考えています。それは単純な文字列「新しいメッセージを待っています...」から始まり、異なることが起こると、新しいメッセージがその文字列に追加されます。コンソールがいっぱいになると、追加のたびにフィールドがスクロールし、コンソールの下部に最新のメッセージが常に表示され、古いメッセージが上部のビューから消えます。Swiftアプリケーション(UILabel、UITextView、スクロール、頭を切り捨てる)で最小限のコンソールを作成する方法

「トランケートヘッド」と複数行のUILabelの方法はありますか?私は最初にUILabelでこれをやろうとしましたが、いつも文字列のENDを表示する方法が見つけられませんでした。 Truncate headは実際に行単位で動作するので、文字列の最初の5行を表示し、最後に表示される行の末尾を表示します。私は様々な配置とラッピング設定を試みたが、何も働かなかった...私は何かを逃している? UILabelに文字列の終わりを常に表示させ、内容が上から消えるようにする方法はありますか?

各回に合わせて文字列をカットしますか?多分、私はちょうど最後の千文字または同様の文字列をカットすることができますか?しかし、私はUILabelがどれほど大きく(別の画面で)表示されるかはわかりません...フォントを自分のものにしても、文字列を整える文字数を正確に知ることはできません。私はそれを与えられた量のSPACEにトリムできず、私のUILabelのスペースの量を得ることができませんか?

または、私はUITextViewとScrollを使用することができます多分これは私がしなければならないことです。テキストビューのテキスト全体の値を取得し、新しい文字列を追加してUITextViewに戻してから、NSMakeRangeと.scrollRangeToBottomを使用して下部にスクロールします。

func updateConsole(switchType: String) { 

     //unwind the console's text 

     if let tempString = consoleZe.text { 
      currentText = tempString 
     } 

     consoleZe.text = currentText + "A new message here! Something clever taken from \(switchType).\n" 

     //Scroll to the bottom 

     let bottom = NSMakeRange(consoleZe.text.characters.count - 1, 1) 
     consoleZe.scrollRangeToVisible(bottom) 
} 

これは、私の小さなアップデートコンソールのための多くの作業のようです。過去の値を見るためにスクロールすることは気にしない。私はさらにコンソールを好むだろうスクロールしなかった...だから、つかむ、追加する、貼り付け、底を取得し、スクロールは余分な、不要な手荷物の多くのようです。

UILabelやUITextViewなどを使用して、最小限のコンソールを実装することに関するすべての考えを歓迎します。ありがとうございます!

答えて

1

私は、テーブルビューと "ConsoleBuffer"クラスをデータソースとして使用して、 "コンソールビューコントローラ"を実装しました。テーブルビューは、メッセージログコンソールの行単位の性質によく対応し、自動スクロールを容易にします。

は、コンソールメッセージを文字列の単純な配列といくつかのヘルパー関数に添付したシングルトンクラスです。

class ConsoleBuffer { 
    struct Prefs { 
     static let defaultLines = 100 
     static let maxLines = 1000 
    } 
    static let shared = ConsoleBuffer() 

    private var buffer = [String]() { 
     didSet { 
      if buffer.count > lines { 
       buffer.removeFirst(buffer.count - lines) 
      } 
      tableView?.reloadData() 
      NSAnimationContext.runAnimationGroup({ (context) in 
       if let tableView = self.tableView { 
        if let scrollView = tableView.enclosingScrollView { 
         let range = tableView.rows(in: scrollView.contentView.visibleRect) 
         let lastRow = range.location + range.length 
         if lastRow == oldValue.count - 1 { 
          context.allowsImplicitAnimation = true 
          tableView.scrollRowToVisible(buffer.count - 1) 
         } 
        } 
       } 
      }, completionHandler: nil) 

     } 
    } 

    var lines = ConsoleBuffer.Prefs.defaultLines { 
     didSet { 
      if lines > ConsoleBuffer.Prefs.maxLines { 
       lines = ConsoleBuffer.Prefs.maxLines 
      } 
     } 
    } 

    var count: Int { 
     get { 
      return buffer.count 
     } 
    } 

    var tableView: NSTableView? 

    private init() { } 

    func line(_ n: Int) -> String { 
     if n >= 0 && n < buffer.count { 
      return buffer[n] 
     } else { 
      return "" 
     } 
    } 

    func add(_ line: String) { 
     let dateStampedLine = "\(Date()) \(line)" 
     buffer.append(dateStampedLine) 
    } 

    func clear() { 
     buffer.removeAll() 
    }  
} 

これらの二つの文は、ConsoleBufferシングルトンを行います:シングルトンを持つ

static let shared = ConsoleBuffer() 
private init() { } 

は、それが簡単に持つことの必要性なしにどこでもあなたのプロジェクトに新しいコンソール行を追加することになり、完全なConsoleBuffer実装は、以下を参照してくださいクラスのインスタンスへの参照。 initをプライベートにすると、誰もConsoleBuffer()を呼び出すことができません。あなたはそのシングルトンインスタンスを使用する必要があります。ConsoleBuffer.shared

コンソール行の文字列はbufferの配列に保持されています。この配列に新しい行を追加すると、最後に追加された行だけスクロールして表示されます。それ以外の場合、スクロール位置は変更されません。

データソースは現在、実装が容易である:あなたが使用するテーブルビューにConsoleBuffertableViewプロパティを設定する必要がテーブルビューコントローラのviewDidLoad機能で

func numberOfRows(in tableView: NSTableView) -> Int { 
    return ConsoleBuffer.shared.count 
} 

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { 
    let cell = tableView.make(withIdentifier: "ConsoleCell", owner: self) as? NSTableCellView 
    cell?.textField?.stringValue = ConsoleBuffer.shared.line(row) 
    return cell 
} 

。また、これはバッファ配列に格納するラインの所望の最大数を設定するための場所である:

ConsoleBuffer.shared.tableView = tableView 
ConsoleBuffer.shared.lines = 500 

今、あなたは、このようなコンソールに新しい行を追加することができます。

ConsoleBuffer.shared.add("console message") 

が、これは取得ホープあなたは正しい方向に進んでいます。

+0

ご協力いただきありがとうございます。私はあなたが共有したコードの大半を理解する能力は十分にあるわけではありませんが、コンソールメッセージを配列に格納するというコンセプトは私には意味があります。これははるかに強力で、表示する量を正確に指定できます異なる状況で似たような試みをする前に、SwiftのtableViewと配列についてもっと知る必要があります。再びありがとう、D. – Beagley

関連する問題