2017-09-15 11 views
1

화면에 활동이나 정보를 표시하기 위해 내 앱에 콘솔을 만들고 싶습니다. 간단한 문자열 인 "새 메시지를 기다리는 중 ..."으로 시작하고 다른 일이 발생하면 새 메시지가 해당 문자열에 추가됩니다. 콘솔이 가득 찼을 때 필드는 추가 될 때마다 스크롤되어 사용자는 항상 콘솔 맨 아래에서 가장 최근의 메시지를보고 상단의보기에서 오래된 메시지가 사라집니다.Swift 앱 (UILabel, UITextView, 스크롤, 머리 자르기)에서 최소 콘솔을 만드는 방법

"머리 잘림"과 다중 줄 UILabel이있는 방법이 있습니까? 먼저 UILabel을 사용하여이 작업을 시도했지만 문자열의 끝 부분을 항상 볼 수있는 방법이 없습니다. Truncate head는 실제로 줄 단위로 작동하므로 문자열의 처음 다섯 줄을 표시하고 마지막으로 보이는 줄의 꼬리를 표시합니다. 다양한 정렬 및 배치 설정을 시도했지만 아무 것도 작동하지 않았습니다 ... 뭔가 빠졌습니까? UILabel에 항상 문자열의 끝을 표시하고 내용이 맨 위에 표시되도록하는 방법이 있습니까?

매번 끈을 자르겠습니다. 어쩌면 나는 지난 1000 자 정도의 문자열을자를 수 있을까? 그러나 나는 UILabel이 (다른 화면에서) 얼마나 큰지 알지 못합니다 ... 글꼴을 그대로 사용하면 문자열을 다듬어야하는 문자의 수를 정확하게 알 수 있을지 의심 스럽습니다. 나는 공간의 주어진 금액에 그것을 잘라 내 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"클래스를 데이터 소스로 사용하여 "콘솔 뷰 컨트롤러"를 구현했습니다. 테이블 뷰는 메시지 로깅 콘솔의 라인 별 특성에 잘 부합하며 자동 스크롤을 쉽게 만듭니다.

ConsoleBuffer은 콘솔 메시지를 간단한 문자열 배열과 첨부 된 일부 도우미 함수로 유지하는 단일 클래스입니다. 전체 ConsoleBuffer 구현은 아래를 참조하시기 바랍니다 :

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

싱글을 갖는 것은이 쉽게를 가질 필요없이 어디서나 프로젝트에서 새 콘솔 줄을 추가합니다 :

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 싱글을 클래스의 인스턴스에 대한 참조. init을 비공개로 설정하면 누구나 ConsoleBuffer()을 호출 할 수 없습니다. 단 하나의 인스턴스 인 ConsoleBuffer.shared을 사용해야합니다.

콘솔 줄 문자열은 buffer 배열에 보관되어있어 구현이 숨겨져 있습니다.이 배열에 새 행을 추가 할 때 이전에 마지막 행이 표시된 경우에만 tableview가 추가 된 마지막 행으로 부드럽게 스크롤됩니다. 그렇지 않으면 스크롤 위치는 변경되지 않습니다.

데이터 소스

이제 구현하기 쉬운 다음의 tableview 컨트롤러의 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 
} 

당신이 사용하는있는 tableview에 ConsoleBuffertableView 속성을 설정해야합니다.

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

지금이 같은 콘솔에 새로운 라인을 추가 할 수 있습니다 :

ConsoleBuffer.shared.add("console message") 

희망이 가져 또한,이 버퍼 배열에 저장하는 라인의 원하는 최대 수를 설정하는 장소입니다 너는 올바른 방향으로 가고있어.

+0

구현을 공유해 주셔서 감사합니다. 필자가 공유 한 대부분의 코드를 이해할 수있는 충분한 능력을 갖추고 있지는 않지만 콘솔 메시지를 배열에 저장하는 개념은 나에게 의미가 있습니다. 훨씬 강력하고 정확하게 표시 할 수있는 양을 지정할 수 있습니다 다른 상황에서. 비슷한 것을 시도하기 전에 Swift에서 tableView와 배열에 대해 더 많이 배워야 할 것입니다. 다시 한번 감사드립니다. – Beagley