2015-01-22 5 views
0

Я ищу способ загрузки вычисленных CGPoints из plist (Xcode 6/Swift).Чтение вычисленных CGPoints из plist

Раньше я использовал CGPoints как Strings в plist в формате {160,450}, загружал строку и конвертировал ее с помощью CGPointFromString().

Поскольку я хочу, чтобы приложение работало на разных устройствах, мне нужно, чтобы эти CGPoints были относительно размера экрана.

Я думал, что можно ввести строку как {kScreenWidth/2, kScreenHeight * 3/4}, но, конечно, это не работает и возвращает CGPointZero. Я предполагаю, что могу написать свой собственный метод CGPointFromString, который учитывает мои константы, но я не знаю, как это сделать, и может быть лучшее решение без строк.

Можно ли сохранить и загрузить это как «данные» в plist? Я пробовал много, но не могу найти решение.

Любые идеи высоко оценены!

Вот код:

let points: [CGPoint] 

init(levelNumber: Int) { 
    let levelDict = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("level\(levelNumber + 1)", ofType: "plist")!)! { 

    self.points = [] 

    if let pointsData = levelDict["pointsData"] as [NSDictionary]? 
    for item in pointsData { 
     let pointString = item["point"] as String 
     self.points.append(CGPointFromString(pointString)) 
    } 
    } 
} 

Тогда я хотел бы создать CGPath из массива точек (знаете, как это сделать).

EDIT: Простое обновление, чтобы сделать мои намерения более ясными.

Мне нужно создать пути, которые будут одинаковыми на всех устройствах, относительно их размеров экрана. CGPoints для пути следует вводить вручную в plist для предварительной настройки нескольких путей. Они не должны вычисляться и сохраняться приложением во время выполнения.

Рассмотрим следующие объявления:

let kScreenWidth = UIScreen.mainScreen().bounds.width 
let sprite = SKSpriteNode(color: UIColor.blackColor(), size: CGSize(width: kScreenWidth/4, height: kScreenWidth/4)) 
let bottomRight = CGPoint(x: kScreenWidth - sprite.size.width/2, y: 0.0) 

В идеальном мире, я бы сохранить следующие два CGPoints в PLIST так же, как я мог бы установить позиции в коде и когда разворачивание, приложение будет знать, чтобы искать эти константы и получить их значение:

(х: kScreenWidth * 1/4, у: sprite.size.width/2)

bottomRight

Я ищу решение как можно ближе! Большое спасибо за помощь!

+0

Вы заглянули в NSValue? –

+0

Привет, Томас, спасибо за ваш ответ! Я сейчас общаюсь с NSValue, но я не понимаю, как я буду использовать его в своем случае. В каком формате мне нужно будет вводить мои CGPoints в plist (я делаю это вручную, чтобы настроить некоторые предварительно сконфигурированные пути, зависящие от размера экрана)? – nontomatic

+0

Я тоже изучил это. NSValue, похоже, не является окончательным путем. Вы не можете сохранить его в NSDictionary. Это должно быть NSData. Я немного зациклен на том, как переложить это в другое. При первом предположении, синтаксический анализ, вероятно, будет проще. Разделите точку с запятой и используйте NSNumberFormatter –

ответ

0

Вы можете использовать следующее расширение:

extension CGPoint { 
    func string() -> String { return "\(self.x);\(self.y)" } 
    mutating func fromString(s:String) { 
    var coords = split(s) {$0 == ";"} 
    x = CGFloat((coords[0] as NSString).floatValue) 
    y = CGFloat((coords[1] as NSString).floatValue) 
    } 
} 

let p = CGPoint(x:1.2, y:3.4) 
println(p.string()) 
var p1 = CGPoint() 
p1.fromString(p.string()) 
println(p1) 

Если вы бежите, что в Playground вы видите, что есть проблема, но точность с координатами чертежа можно пренебречь тем.

Предполагая, что у вас есть PLIST с этой записью:

<dict> 
    <key>myPoint</key> 
    <string>1.2;3.4</string> 
</dict> 

После вашего

let levelDict = NSDictionary(contentsOfFile: NSBundle.mainBundle().pathForResource("level\(levelNumber + 1)", ofType: "plist")!)! 

вы можете распаковать CGPoint как

var p = CGPoint() 
p.fromString(levelDict["myPoint"] // now it's CGPoint(x:1.2,y:3.4) 

Чтобы сохранить его обратно вам необходимо установить

levelDict["myPoint"] = p.string() 

перед написанием plist из словаря в файл.

+0

Большое спасибо, что действительно учитывает постоянные переменные! Однако мне все равно нужно сохранить данные в виде CGPoints в plist. Я полагаю, что в качестве альтернативы можно было бы сохранить CGPoints в виде строк, включая имена переменных, а затем расширить NSString для преобразования в CGPoint аналогично тому, как вы это делали выше? Я попробую и отправлю отчет сегодня вечером. Если мне что-то не хватает, сообщите мне, вы, очевидно, гораздо более опытны, чем я! Большое спасибо! – nontomatic

+0

Вышеупомянутое учитывает, что вы сохраняете их как String в plist. Я исправлю ответ. –

+0

Извините за задержку, я не мог попробовать код раньше. Большое спасибо за то, что нашли время, чтобы напечатать это, высоко оценили! По-видимому, он не работает с моими вычисленными переменными. Я объявил 'let kScreenWidth = UIScreen.mainScreen(). Bounds.width let kScreenHeight = UIScreen.mainScreen(). Bounds.height' Я ввел точку в виде строки в plist:' kScreenWidth/2; kScreenHeight/Xcode сломается с фатальной ошибкой: «Невозможно проиндексировать пустой буфер», указывая на строку x = расширения CGPoint. – nontomatic

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

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