2017-02-10 5 views
0

мне нужно отформатировать столбец чисел в textView отображая столбец дробных и десятичных чисел и выравнивая их так, десятичную точку или вперед символов слэш появляются в той же колонке, как так ...есть лучший способ выровнять этот столбец чисел в Swift textView?

x  1/1 
    1  76.04900 
    x 193.15686 
    x 310.26471 
    4  5/4 
    x 503.42157 
    6 579.47057 
    x 696.57843 
    x  25/16 
    9 889.73529 
    x 1006.84314 
    11 1082.89214 

Это был достигнут в Swift, вставив соответствующее количество ведущих символов пробелов и используя левое выравнивание с шрифтом, где ширина столбца одинакова для каждого символа.

Чтобы вычислить количество пробелов, символы в остатке или дивиденды исключены из общего количества символов в каждом номере. Эта простая задача включала в себя вычитание .index(of:) из .count и осложняется тем, что .index(of:) возвращает дополнительный Array.Index? не Int?

Я подозреваю, что может быть более простой способ добиться того же результата и приветствуем любые улучшения в Swift код ниже, что может облегчить жизнь тем, кто должен его поддерживать. Код был извлечен из моего проекта и был протестирован на Playground.

Примечание. textMessage - это одна строка. Он отображается в области отладки. Он будет отображаться в textView.

//: Playground 

    import UIKit 

    var tuningArray   = ["1/1", "76.04900", "193.15686", "310.26471", "5/4", "503.42157", "579.47057", "696.57843", "25/16", "889.73529", "1006.84314", "1082.89214"] 
    var keyArray    = ["x", "1", "x", "x", "4", "x", "6", "x", "x", "9", "x", "11"] 

    var characterCountArray = [Int]() 
    var scaleSize    = Int() 
    var textMessage   = String() 



    func formatTextMessage() { 
    var formattedTextArray  = [String](repeating: "", count: scaleSize) 

    for i in 0..<scaleSize { 
     let element   = tuningArray[i] 
     countNumericCharactersBeforeDotOrSlash (s: element) 
     } 

    let largestStringSize  = characterCountArray.reduce(Int.min, { max($0, $1) }) 

    for i in 0..<scaleSize { 

     let thisStringSize  = characterCountArray[i] 
     let blanks    = largestStringSize - thisStringSize 
     let filler    = insertWhiteSpace(count: blanks) 

     formattedTextArray[i].append("\t" + keyArray[i] + "\t" + filler + tuningArray[i] + "\n") 
     textMessage   += formattedTextArray[i] 
     } 
    print(textMessage) 
    } 



    func insertWhiteSpace(count: Int) -> String { 
    var filler     = "" 
     for _ in 0..<count { 
     filler     = filler + " " 
     } 
    return filler 
    } 



    func countNumericCharactersBeforeDotOrSlash (s: String) { 

    let fractionalNumber  = findFractionalNumber(s: s) 
    let decimalNumber   = findDecimalNumber(s: s) 
    var thisStringSize   = 0 

    if !fractionalNumber && !decimalNumber { 
     print("Error: invalid number format") 
    } 

    if fractionalNumber  == true { 

    let pitchStringArray  = Array(s.characters) 
    let endIndex    = pitchStringArray.count 

    if let slashIndex   = pitchStringArray.index(of: "/") { 
     let dividendFiller  = endIndex - slashIndex 
     thisStringSize   = s.characters.count - dividendFiller 
    } 

    } else { 

    if decimalNumber   == true { 

     let pitchStringArray = Array(s.characters) 
     let endIndex   = pitchStringArray.count 

     if let dotIndex  = pitchStringArray.index(of: ".") { 
      let remainderFiller = endIndex - dotIndex 
      thisStringSize  = s.characters.count - remainderFiller 
      } 
     } 
     } 
    characterCountArray.append(thisStringSize) 
    } 



    func findDecimalNumber(s: String?) -> Bool { 
    if (s?.contains("."))  == true { 
     return true 
     } 
     return false 
    } 



    func findFractionalNumber(s: String?) -> Bool { 
    if (s?.contains("/"))  == true { 
     return true 
     } 
     return false 
    } 



    scaleSize     = tuningArray.count 
    formatTextMessage() 
+0

Грег, Вы хотите, чтобы выровнять текст, как и выше? выглядеть как табличный formate? –

+0

Да. Подобно Word или Excel, кроме цифр, необходимо выровнять по столбцу десятичной или прямой косой черты, чтобы соответствовать стандарту весов, используемому в Scala (см. Http://www.huygens-fokker.org/microtonality/scales.html). – Greg

+0

Все ваши десятичные числа должны быть выровнены одинаково, как показано выше. то есть все ». должен быть в строю. –

ответ

1

Вы можете использовать приписывали текст с пользовательскими символами табуляции, как в этом примере:

import UIKit 
import PlaygroundSupport 


var tuningArray   = ["1/1", "76.04900", "193.15686", "310.26471", "5/4", "503.42157", "579.47057", "696.57843", "25/16", "889.73529", "1006.84314", "1082.89214"] 

var keyArray = ["x", "1", "x", "x", "4", "x", "6", "x", "x", "9", "x", "11"] 
let scaleSize = tuningArray.count 
var textMessage = "" 

for i in 0..<scaleSize { 
    var textLine = "\t" + keyArray[i] + "\t" + tuningArray[i] + "\n" 
    textMessage += textLine 
} 

let paragraphStyle = NSMutableParagraphStyle() 
let decimalTerminators:CharacterSet = [".", "/"] 
let decimalTabOptions = [NSTabColumnTerminatorsAttributeName:decimalTerminators] 
let decimalTabLocation = CGFloat(100) // TODO: Calculate... 
var decimalTab = NSTextTab(textAlignment: .natural, location: decimalTabLocation, options: decimalTabOptions) 
var leftTab = NSTextTab(textAlignment: .left, location: CGFloat(0.01), options: [:]) 
paragraphStyle.tabStops = [leftTab, decimalTab] 

var a = NSAttributedString(string:textMessage,attributes: [NSParagraphStyleAttributeName: paragraphStyle]) 

let tv = UITextView(frame:CGRect(x:0, y:0, width:400, height:200)) 
tv.attributedText = a 
PlaygroundPage.current.liveView = tv 

Единственным недостатком является то, что вы должны вычислить положение язычка десятичного каким-то образом; в примере я просто использую CGFloat(100), чтобы получить хорошее значение. Но, может быть, вы могли бы просто так жить.

Screenshot

+0

Андреас, ты сделал это намного проще, чем мой оригинальный код. Благодарю. Теперь я пытаюсь заставить его работать в проекте Xcode в ViewController, где tv появится внутри StackViewController. Swift все еще новенький для меня, поэтому мне нужно больше времени, чтобы полностью проверить этот ответ. Будьте уверены, я вернусь к вам, как только я буду уверен в ее принятии. – Greg

+0

Андреас, ты жемчужина! Ваше решение уменьшило мой код до одной функции, которая теперь работает в моем проекте Xcode. Это должен быть принятый ответ. – Greg

+0

Андреас, я сделал это дальше, но это не совсем так. Если вы можете сэкономить минуту, пожалуйста, взгляните. http://stackoverflow.com/q/42298647/2348597 Спасибо. – Greg

1

Грег, Вместо того, чтобы использовать пространство для установки колонок используйте вкладку (\ т) дерево для времени, основанной на столбцы размера вам нужно. Это поможет лучше управлять кодом с очень низким и мощным кодированием.

Благодаря

+0

Ashwin, вы имеете в виду использование '' \ t "' only, вместо '' \ t "+ filler'? - как у меня есть в формате formattedTextArray [i] .append ("\ t" + keyArray [i] + "\ t" + filler + tuningArray [i] + "\ n") ' – Greg

+0

Да, вы можете управлять им с помощью только \ t. но single \ t не поможет. вам нужно добавить несколько вкладок на основе максимальной длины текста. –

 Смежные вопросы

  • Нет связанных вопросов^_^