2017-02-03 5 views
0

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

class Utilities: NSObject { 

    //Red, Green, Blue, Yellow, Purple 
    public let mColors = ["#DA4167", "#81E979","#2B3A67", "#FFFD82", "#3D315B"] 

    class func hexStringToUIColor (hex:String) -> UIColor { 
     var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() 

     if (cString.hasPrefix("#")) { 
      cString.remove(at: cString.startIndex) 
     } 

     if ((cString.characters.count) != 6) { 
      return UIColor.gray 
     } 

     var rgbValue:UInt32 = 0 
     Scanner(string: cString).scanHexInt32(&rgbValue) 

     return UIColor(
      red: CGFloat((rgbValue & 0xFF0000) >> 16)/255.0, 
      green: CGFloat((rgbValue & 0x00FF00) >> 8)/255.0, 
      blue: CGFloat(rgbValue & 0x0000FF)/255.0, 
      alpha: CGFloat(1.0) 
     ) 
    } 
} 

Как я могу использовать mColors в другом классе? У меня есть еще один класс, где я пытаюсь использовать mColors, это линия:

mRingOne.fillColor = Utilities.hexStringToUIColor(hex: mColors[0]) 

Я получаю эту ошибку:

Use of unresolved identifier 'mColors' 
+2

классов Utility почти всегда плохое решение. 'hexStringToUIColor', вероятно, будет лучше, чем расширение' UIColor' – Sulthan

+0

Спасибо, я думаю, что пока буду придерживаться этого класса, так как мне нужно добавить туда больше методов. – swiftnewbie

+1

Это не Java. Как указывали Султан и Хэмиш, Свифт позволяет нам распространять другие народы. Мы используем их, когда это возможно, вместо того, чтобы создавать произвольные классы полезности для всех методов bastard-child, которые не подходят нигде. – Alexander

ответ

1

Как @Sulthan says, вы действительно не должны использовать класс утилиты для этого (намного меньше не- final служебный класс, который наследуется от NSObject!).

Вы должны переместить hexStringToUIColor в расширение UIColor, которое я бы посоветовал вам также сделать инициализатор удобства. Если вы все еще хотите пространство имен, вы можете использовать безвизовый enum (это предпочтительнее, чем struct или class, так как это предотвращает интилизацию).

Также я бы посоветовал использовать массив для хранения ваших шестнадцатеричных строк (если вам действительно не нужно перебирать их по какой-либо причине). mColors[0] не говорит «красный», поэтому сделайте их static свойствами с фактическими именами. Вероятно, они также были бы более полезными как UIColor объектов, а не String.

Вот пример из этих предложений:

extension UIColor { 

    convenience init(hex: String) { 

     var hex = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() 

     if hex.hasPrefix("#") { 
      hex.remove(at: hex.startIndex) 
     } 

     guard hex.characters.count == 6 else { 
      self.init(cgColor: UIColor.gray.cgColor) 
      return 
     } 

     var rgbValue: UInt32 = 0 
     Scanner(string: hex).scanHexInt32(&rgbValue) 

     self.init(
      red: CGFloat((rgbValue & 0xFF0000) >> 16)/255, 
      green: CGFloat((rgbValue & 0x00FF00) >> 8)/255, 
      blue: CGFloat(rgbValue & 0x0000FF)/255, 
      alpha: 1 
     ) 
    } 
} 

enum MySpecialColors { 
    static let red = UIColor(hex: "#DA4167") 
    static let green = UIColor(hex: "#81E979") 
    static let blue = UIColor(hex: "#2B3A67") 
    static let yellow = UIColor(hex: "#FFFD82") 
    static let purple = UIColor(hex: "#3D315B") 
} 

Теперь, если вы хотите использовать цвета, вы просто говорите такие вещи, как:

mRingOne.fillColor = MySpecialColors.red 
+0

Какой файл следует открыть для расширения? Я действительно новичок в Swift и стараюсь практиковать хорошее программирование. Спасибо – swiftnewbie

+0

@swiftnewbie Вы можете поместить его в свой собственный .swift-файл или просто вставить его в верхнюю часть одного из ваших существующих .swift-файлов в свой проект - он будет доступен во всем вашем проекте (ну, технически модуль). – Hamish

+0

спасибо. – swiftnewbie

1

Перемещение этой линии:

public let mColors = ["#DA4167", "#81E979","#2B3A67", "#FFFD82", "#3D315B"] 

... на «верхний уровень», то есть поместить его в за пределами любых фигурных скобок (например, таких как объявление класса, где оно сейчас находится).

//Red, Green, Blue, Yellow, Purple 
public let mColors = ["#DA4167", "#81E979","#2B3A67", "#FFFD82", "#3D315B"] 
class Utilities: NSObject { 

EDIT Теперь я сожалею, что я предложил это. Класс Utility не является классом - это просто пространство имен для некоторых констант и функций. Пространства имен хороши. Было бы лучше, поэтому, чтобы иметь со статическими-структуру членов, как это было предложено в другой ответ:

struct Utilities { 
    static let mColors = ["#DA4167", "#81E979","#2B3A67", "#FFFD82", "#3D315B"] 
    // ... 
} 

Синтаксис для доступа из любой бы тогда Utilities.mColors.

+0

И посмотри мою книгу. Кудрявые скобки - это _scope_: http://www.apeth.com/swiftBook/ch01.html#_scope_and_lifetime – matt

+0

Спасибо, работая в префектуре. – swiftnewbie

+0

Но теперь у меня «раскаяние ответчика». Я изменил свой ответ. Другой ответ должен быть принят. – matt

0

набор mColors, как статические:

static let mColors = ["#DA4167", "#81E979","#2B3A67", "#FFFD82", "#3D315B"] 

и называют его:

mRingOne.fillColor = Utilities.hexStringToUIColor(hex: Utilities.mColors[0]) 

Вы можете сделать статический позволяет каждому цвету:

static let myRed = "#DA4167" 
static let myGreen = "#81E979" 

и называем его :

mRingOne.fillColor = Utilities.hexStringToUIColor(hex: Utilities.myRed) 
+0

Большое спасибо. Однако я пошел с первым ответом. – swiftnewbie

+1

Вообще-то этот ответ лучше моего. Класс вашей утилиты не является классом - это просто пространство имен для некоторых констант и функций. Было бы лучше как класс (или даже лучше, структура) со статическими членами. Тогда синтаксис для доступа будет «Utilities.mColors». – matt

+0

Спасибо вам обоим. – swiftnewbie