顯示具有 swift 標籤的文章。 顯示所有文章
顯示具有 swift 標籤的文章。 顯示所有文章

2020年6月29日 星期一

[iOS] JSON

JSON

JavaScript Object Notation,是輕量級的資料交換語言,與Swift的字典相當類似,使用key對應value,並且可以儲存String、Int、Double以及Array,透過JSON可以很方便的從別的平台取得資料,接著轉換成Swift程式語言可使用的格式。

{
  "a" : "a",
  "b" : 0,
  "c" : 0.5,
  "d" : [1,2,3,4,5],
  "e" : {
    "e1": "e"
  }
}

以上是一個簡單的JSON結構,大括號【 {} 】代表物件,中括號【 [] 】代表陣列,一樣是使用

雙引號代表字串,冒號的左方為key,右方為value。

所以我們使用以上的JSON,拿字串a代表key的話,會取出字串a這個value,依此類推。

通常整個JSON是一個字串,我們可以透過轉換將JSON字串轉換成JSON,舉例來說,我們先使用字串構建一個JSON。

        let jsonString = """
        {
          "a": "a",
          "b": 1,
          "c": 1.1
        }
        """

我們可以到網站上驗證我們的JSON字串是否合法


確認是一個合法的JSON字串後,我們試著將它轉換成Swift可使用的資料格式,

前面有提到JSON其實與字典十分類似,因此你可以將JSON字串轉換成字典。 

        //將JSON字串轉換成Data
        if let jsonData = jsonString.data(using: .utf8) {
            do {
                //透過JSON序列化轉換成自字典物件
                if let dictionary = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
                    print(dictionary["a"]!) //a
                    print(dictionary["b"]!) //1
                    print(dictionary["c"]!) //1.1
                }
            } catch {
                print(error.localizedDescription)
            }
        }



但是透過字典來取JSON其實還是有些麻煩,更好的作法應該是將JSON轉換成物件,不管是Class或Struct的形式均可,因此這邊說明如何將JSON轉換成物件。

首先我們必須要建立一個相同的物件格式,以上面的例子來說

struct MyJSONModel {
    var a: String
    var b: Int
    var c: Double
}

接著我們必須遵循Codable協議

struct MyJSONModel: Codable {
    var a: String
    var b: Int
    var c: Double
}

如此一來你就可以將JSON轉換成這個結構的實體

透過JSONDecoder來將JSON Data轉換成結構的實體

//將JSON字串轉換成Data
if let jsonData = jsonString.data(using: .utf8) {
    do {
        let jsonDecoder = JSONDecoder()
        let myJSONModel = try jsonDecoder.decode(MyJSONModel.self, from: jsonData)
        print(myJSONModel.a) //a
        print(myJSONModel.b) //1
        print(myJSONModel.c) //1.1
    } catch {
        print(error.localizedDescription)
    }
}

當然反過來也可以,你可以將結構實體透過JSONEncoder轉換成JSON Data

let myJSONModel = MyJSONModel(a: "AA", b: 1, c: 0.2)
let jsonEncoder = JSONEncoder()
do {
    let jsonData = try jsonEncoder.encode(myJSONModel)
} catch {
    print(error.localizedDescription)
}



有幾個點必須注意的,你的struct或class定義的屬性,一定要與JSON一致,JSON的Value是整數就必須定義成整數,如果有些時候,這個值可能不存在,就必須定義成可選型別。

變數名稱也必須與JSON的Key相符,若是不相同,則會解析失敗,

有些時候JSON的Key可能與Swift的命名有些衝突,舉例來說有個JSON格式如下

{
    "Name": "Jerry",
    "Age": 18,
}

如果我們想要使用這個JSON,且是轉換成struct或class的話,就得這樣定義

struct User: Codable {
    var Name: String
    var Age: Int
}

但是我們都知道,Swift的命名規則,常數與變數名稱應該為小寫開頭的,因此這樣的命名不是太妥當

你可以一樣將變數命名成小寫,並增加一個enum CodingKeys,且資料型態為String,實作CodingKey這個Protocol。

struct User: Codable {
    var name: String
    var age: Int
    
    
    enum CodingKeys: String, CodingKey {
        case name = "Name"
        case age = "Age"
    }
}

enum的case為你的所有變數名稱,後方則是JSON對應的Key真正的樣子,如此一來,即使JSON的Key與Swift的命名有出入,也可以更換成我們習慣的命名規則。

let jsonString = """
{
  "Name": "Jerry",
  "Age": 18
}
"""

//將JSON字串轉換成Data
if let jsonData = jsonString.data(using: .utf8) {
    do {
        let jsonDecoder = JSONDecoder()
        let user = try jsonDecoder.decode(User.self, from: jsonData)
        print(user.name) //Jerry
        print(user.age) //18
    } catch {
        print(error.localizedDescription)
    }
}

此外,你可以解析JSONDecoder所拋出的例外


            do {
                let jsonDecoder = JSONDecoder()
                let myJSONModel = try jsonDecoder.decode(JSONModel.self, from: jsonData)
            } catch DecodingError.keyNotFound(let key, let context) {

            } catch DecodingError.typeMismatch(let type, let context) {
                
            } catch DecodingError.valueNotFound(let type, let context) {
                
            } catch  {
                
            }



2020年6月18日 星期四

[iOS - Swift] extension

extension,擴展,用於在既有的Class Struct Enum上增加額外的功能。

class MyClass {
    
}

extension MyClass {
    func sayHello() {
        print("Hello")
    }
}

let myClass = MyClass()
myClass.sayHello()

也可以於原生提供的Class增加額外的功能。

extension String {
    func toIntValue() -> Int? {
        return Int(self)
    }
}

let string = "3"
print(string.toIntValue())

這種情況叫做Category,通常會開一個新的檔案,命名為要擴展的Class+

例如:
String+.swift

擴展也能拿來實作Protocol

extension ViewController: UITableViewDelegate {

}

2020年6月17日 星期三

[iOS - Swift] Date的使用方式

Date是專門用來處理有關時間的一個類別。
我們可以簡單的透過以下的程式碼來取得當前時間。

let date = Date()

接著透過DateFormatter來進行時間的轉換,因為我們可能會需要將時間轉換成字串,以便顯示,或者進行處理。

///取得當前時間
let date = Date()
///時間轉換成字串
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy/MM/dd"
print(dateFormatter.string(from: date))
我們可以透過網站得知一些時間的格式應該怎麽使用

透過設定dateFormat,來讓Date轉換成你想要的時間格式。
如果轉換出來的結果可能會依照語系的不同,可以經由設定語系來更改

///取得當前時間
let date = Date()
///時間轉換成字串
let dateFormatter = DateFormatter()
///設定語系
dateFormatter.locale = Locale(identifier: "zh_tw")
dateFormatter.dateFormat = "MMMM"
print(dateFormatter.string(from: date))

當然,你也可以透過文字轉換回Date

let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "zh_tw")
dateFormatter.dateFormat = "yyyy/MM/dd"
if let myDate = dateFormatter.date(from: "2018/12/21") {
    print(myDate)
}
至於日期的增減則可以使用Calendar來處理
let date = Date()
///加三天
let newDate = Calendar.current.date(byAdding: .day, value: 3, to: date)!
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "zh_tw")
dateFormatter.dateFormat = "yyyy/MM/dd"
print(dateFormatter.string(from: newDate))

日期的比較,因為Date有實作Comparable這個Protocol,因此可以很簡單的使用> < = 來進行日期的比較。

let date = Date()
let newDate = Calendar.current.date(byAdding: .day, value: 3, to: date)!
if date < newDate {
    print("Date < NewDate")
}
if date > newDate {
    print("Date > newDate")
}
if date == newDate {
    print("Date == newDate")

2020年1月2日 星期四

[iOS] 讓ScrollView顯示indicators

有時候有些畫面可以捲動,可是使用者不一定知道這個畫面可以捲動,你可以於每次顯示此畫面時,呼叫flashScrollIndicators函式,讓ScrollView相關類別顯示一下Indicators,這樣會讓使用者知道這個頁面可以捲動。

使用效果就會像是這個樣子,可捲動的Indicators會顯示出來。



2019年11月12日 星期二

[iOS] 等寬字體

有時候會需要等寬字體,像是顯示數字時,希望位數相同的可以對齊,若是你設定的字體非等寬字體的話,就會像以下這個樣子。












你可以使用CourierMenlo兩種等寬字體來解決此問題

Courier
























Menlo













2019年10月31日 星期四

[iOS] 文字轉語音

如果你想要讓你的App有朗讀的功能,也就是文字轉語音,使用方式非常的簡單。

首先要import AVFoundation,

接著只需要寫以下的程式碼即可。

2019年10月14日 星期一

[iOS] Swift some 與 Opaque Result Types

Swift5.1之後出現了SwiftUI,學習時發現了一個新的關鍵字some


因此稍微研究了一下有關some的使用方式。

簡單的說當你的Protocol有associatedtype或Self時,Swift無法得知你的具體類型為何。

我們先來看一般狀況的Protocol,我們有個Animal的Protocol,並且有兩個struct去實作它。

此時我們寫一個Func,可以取得一個Animal

一切都很美好,但是如果我們想在Protocol加入associatedtype,像是以下的程式碼。

接著你會發現原本的取得Animal方法被發出警告訊息

原本的做法,你必須改成以下的寫法


使用時也必須指定資料型態


整體來說並不是太方便,因此多了some關鍵字,我們只需要將原本的程式碼改成以下的樣子

如此一來就可以很方便的使用,使用時也不必指定資料型態。


但是要注意的是,若是你的Func有多種類回傳值,分別是不同的實作該Protocol是不行的。


簡單的說some會依照你的回傳值來判斷是哪個類型實作了該Protocol,你不用特別指定哪個類型,而是依照你回傳的值來決定。

舉一個比較常見的例子,Equatable這個Protocol,它的定義如下。


你必須實作==這個Func才算符合Equatable這個Protocol,我們都知道Int有實作該Protocol,因此我們寫一個Func,來隨機產生一個Int,可是我們希望回傳的資料型態是Equatable。



經過上面的例子我們知道是不行的,因為Equatable裡面有使用到Self,因此必須加上some關鍵字。

我們加上some之後,我們繼續增加另一個產生字串的Func,一樣回傳Equatable。

接著我們呼叫這兩個方法,將它們的值取出。


會發現,兩個都是Equatable資料型態,那我們來使用==方法看看。


事實上是不行的,因為雖然表面上都是Equatable,實際上一個是Int,一個是String,雖然我們看不出來,但是Xcode很聰明的看出差異了。

但是如果來源都是同一個Func所Return的值,Xcode會視為相同的。


如果你有兩個Func所Return的值是相同的,Xcode也會認為不同哦,它只認Func,不認回傳值。


2019年9月9日 星期一

[iOS] UITableView - 基礎2

透過基礎1中我們學會了如何使用UITableView。

若是還沒看基礎1,可以透過以下連結前往

基礎1


接下來我們可以使用UITableViewDelegate來取得使用者點選了哪個Cell。

我們先建立簡單的UITableView,可以透過基礎1的結果繼續往下做。

接著在我們的ViewController,透過extension來實作UITableViewDelegate



此時你會發現Xcode並沒有任何變化,因為UITableViewDelegate這個Protocol,所有的func都是可選的,因此就算你一個func都沒有實作,它也認為你已經實作了此Procotol。

但是我們會需要知道使用者點選了哪個Cell,我們可以在Xcode輸入以下的文字

tableviewdid

接著靠Xcode的自動完成功能,選擇我們所需要的func


tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

為UITableViewDelegate Protocol的其中一個func,當使用者點選了任何一個Cell時,將會觸發,會回傳兩個值,分別是你所點選的tableView是何者,以及所點選的indexPath,接著我們將func寫入以下程式碼,使用者點選時會印製log出來。



最後不要忘記在viewDidLoad指定delegate 哦,以下為完整程式碼。



你可以試著執行看看程式,點選其中一個Cell的時候,應該會有訊息印製出來哦。


[iOS] UITableView - 基礎1

UITableView,是一種表格化顯示的View,可以從各式各樣的App當中看見它的身影,是十分常見的一種View。

這邊來介紹最基本的使用方式,首先先開啟一個新的專案,並且於StoryBoard中,加入UITableView,並且設置簡單的Constraint,將UITableView佔滿UIViewController。


接著,我們建置IBoutlet,將UITableView與我們的UIViewController class做關聯,以下我們命名為tableView。


下一步,如果要使用UITableView,我們必須實作UITableViewDataSource這個Protocol。

因此我們加入extension,讓我們的ViewController去實作UITableViewDataSource,此時你會發現Xcode自動發出警告,若是要實作這個Protocol,必須實作一些方法


按下Fix後,XCode會自動幫你產生所需要的程式碼。

必須要實作兩個方法。

tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int

你必須告訴tableView,你要顯示幾個Row

tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

你必須告訴tableView,每個Row所顯示的Cell

接著我們先切回StoryBoard,並且搜尋UITableViewCell,將UITableViewCell拖曳到UITableView裡面。


接著我們選擇這個Cell,然後於右邊的屬性配置區,輸入這個Cell的Identifier,我們將它命名成『MyCell』。


下一步我們可以回到程式碼,將不足的部分補齊,首先我們告訴TableView,我們需要10個Row。

接著我們將下一個程式碼也補齊,我們透過剛才於Storyboard設置的Identifier來取得Cell,並且設置顯示的文字。

最後於viewDidLoad,將tableView的dataSource設置為我們的ViewController,以下是完整的程式碼。

以及執行結果。

以上就是TableView,最基本的用法,要使用就必須實作UITableViewDataSource這個Protocol。

接下來可以看基礎2學習如何使用UITableViewDelegate來捕捉使用者點選了哪個Cell哦。

基礎2

2019年8月30日 星期五

[iOS] PropertyWrapper屬性包裝器

PropertyWrapper,屬性包裝器,透過屬性包裝器,來針對屬性進行包裝。

舉例來說,我們希望某個變數它永遠都是大寫。


我們可以在使用的時候再將它轉換,可是感覺有些麻煩,因此我們可能會寫成這樣


但是這樣寫初始化的時候並不會進入didSet,因此只能很勤勞的在建構子也加入轉換大寫的程式碼。


終於大功告成了,但總的來說並不夠美觀,因為如果有更多的屬性,那不就要在每個屬性的didSet,與建構子中加入程式碼,此時,屬性包裝器就可以派上用場了。

我們建立一個Struct,命名成Uppercased,並在它的上方加入@propertyWrapper關鍵字。

接著Xcode會提示說,propertyWrapper需要有一個名為wrappedValue的屬性,我們將這個屬性加入,並且做一些處理。


程式碼做的事情就是將wrappedValue在set的時候轉換成大寫存在value變數之中,get的時候就取出轉換成大寫的value變數,基本上跟上方獨立處理是差不多的,但是這時候神奇的事情發生了,我們回到Data結構裡面,把title前方加入@Uppercased來修飾。



這樣這個title就被我們自定義的屬性包裝器包裝過了,此時要存取這個屬性都會透過包裝器來存取,就永遠都是大寫了。

有一個例子我覺得還不錯,存取UserDefault就可以使用屬性包裝器。


存取的時候透過屬性包裝器直接存入到UserDefault之中,就可以不需要寫一堆重複的程式碼了。

2019年7月3日 星期三

[iOS] Float轉換成Double時,會有些許的誤差

有時候我們可能會把Float轉換成Double。

像是使用UISlider時,將它的Value取出後,轉換成Double。

但是要特別小心此問題,轉換的時候,會有精度上的誤差,

舉例來說,以下的程式碼的結果可能會跟你想像的不太一樣。

因為Float的精度與Double的不一樣,即使小數點只有幾位的情況下,

轉換過去也是有可能有精度上的誤差。

因此使用時必須特別小心。

2018年6月26日 星期二

[iOS] Singleton的產生語法

有時候整個App生命週期可能需要某幾個只有一個實體的Class,

這時候可以使用Singleton來達成,以下是產生Singleton的程式碼。

Swift


Objective - C



2018年6月14日 星期四

[iOS] 利用xib來製作客製化View

圖片能點擊放大

1. 新增一個客製化的View,命名成為你需要的名稱,且繼承於UIView


2.新增一個同名的xib,此時你的專案應該會有兩個檔案






3.  開始設計你的View,這邊簡單的放入一個Button,並且改為綠色


4. 點選上方的File's Owner類別後,將右邊的Custom Class設置為你的Class名稱。



5.此時你應該可以加入IBoutlet與IBAction了,我們加入一個IBAction,在Touch Up Inside時會印出Log。


6. 此時你的程式碼應該只有這樣


7. 接著我們要override兩個事件,init(frame: CGRect)以及init?(coder aDecoder: NSCoder),此時你的程式碼應該如下。


8. 增加一個loadXib的方法,並填入以下的程式碼

這邊主要是使用nib載入xib的View,並加入到這個Class的View,在設置Autolayout讓畫面呈現。

將loadXib方法加入到剛才override的事件之中,此時完整程式碼應該如下。



如此一來,你就能正常使用這個客製化View了。

可以直接在StoryBoard上面,加入一個View,並將Class設置為你的客製化View



 當然,你也可以使用Code產生這個View後在加入到當前頁面上。


2017年11月13日 星期一

[iOS] 有關UITextField反白區域與游標位置

如何得知目前使用者的游標位置或者是反白區域,可以參考以下的程式碼。

Objective-C



Swift



而如果你需要改編游標位置或者是反白區域,可以參考以下的程式碼。

Objective-C



Swift


2017年8月21日 星期一

[Swift] Associatedtype - Protocol中的泛型

假設我們有個需求是當實作某個Protocol時,其中有些方法傳入的資料型態可能是由實作者來定義的,就可以使用Associatedtype。

舉例來說,有個Animal的Protocol,在實作的時候,實作者可以定義這個動物吃的資料型態,並實作吃食物的方法,以下可以參考程式碼。


此外,如果想要將泛型範圍縮減一點也是可以的,繼續拿這個例子來說,假設我們想定義一個寵物的Protocol,而裡面必須要是有實作過動物的資料型態才可以,你可以參考以下的程式碼。


2017年7月20日 星期四

[iOS] DateFormatter要注意的問題

要將Date轉成字串你可能會使用DateFormatter來轉換,

但是,DateFormatter有一個必須要注意的地方,很多人可能會忽略了這一點,

可以參考一下以下的程式碼。


取得今天的日期,使用DateFormatter將Date的年份取出,並印出。

可以期望會印出2017年,因為今年是2017年,一般來說的確也會印出2017。

但是有可能有例外發生,當使用者自行設定手機的歷別時,就會發生問題了。

在設定 > 一般 > 語言與地區 > 行事曆,這邊可以更改歷別

當你在執行一樣的程式碼的時候,你會發現不是印出你熟悉的年份了



如果你還是想印出2017年,你就必須將DateFormatter指定為西曆,詳細可以參考以下程式碼。

2017年7月3日 星期一

[Swift] JSON解析

Swift提供了JSON原生解析,詳細你可以參考以下的說明。

首先,先寫一個基本的類別,並實作Codable,如果類別中有使用到Enum,也必須實作Codable。

接著,如果你產生這個類別的物件,接著你就可以將此物件轉換成JSON字串。


此時,你應該會看到以下的成果

JSONString = {"age":27,"scores":[90,55,30],"gender":"M","name":"Tom","birthday":-355132800}


這時候你可能會希望生日的部分可以符合開始輸入進去的格式,你增加以下的程式碼,將日期格式指定一下即可。

接著你應該能夠看到符合你預期的結果了

那如果要反過來該怎麼辦呢,把JSON字串轉成物件,也是做的到的,可以參考以下的程式碼


你可以在最後的地方下中斷點看一下是否有轉成符合你預期的物件了。

















這個算是一個相當好用的東西,可以省去自己解析的困擾,除了提供基本的字串,數值以外,也有提供陣列,列舉與日期,涵蓋範圍算是相當廣,當然,物件裡面有其他類別也是可以的,這邊就不做示範,反正就是實作Codable就可以了。

2016年7月5日 星期二

[iOS] UILabel顯示不同的顏色與字型

有些時候會在同一行裡面顯示不同的字體顏色、大小、字型等,比較笨一點的作法是使用多個UILabel來達成,可是這樣寫起來不怎麼好看也不易管理。

因此,如果想要在同一個UILabel指定不同的字體Style該如何達成呢?

首先先開啟一個新的專案,並將UILabel設置在ViewController之中,接著拉出IBOutlet,為了等等設置文字之用。

比較常會使用的類型有以下兩種

NSFontAttributeName,必須提供UIFont來進行設定

NSForegroundColorAttributeName,必須提供UIColor來進行設定。

接著要注意的是,你必須指定哪幾個字要更改顏色或字體大小,因此會用到NSMakeRange來判斷你的位置。

NSMakeRange要丟入起始點,與要從起始點開始算幾個字。

大概知道觀念後,可以直接看Code來理解

Swift


Objective-C



如此一來你會得到以下的效果


2016年2月22日 星期一

[iOS] AutoLayout 筆記 - 設定距離的小技巧2

上次提到設定距離的小技巧,還有一些東西可以補充。

首先先拉出一個100 x 100 ,且水平垂直置中的View






















點Center Y這條線,並將First Item打開,會看到許多選項






















Center Y,代表的意思就是你的View的中心位於這條線上。

你可以試著將他調成Top,此時你的View的Top會位於這條線上。



















接著你將他調整成Bottom,你大概會猜出,此時這個View的Bottom會位於這條線上。



















接著你試著按另一條線,Center X,在First Item一樣有三個選項可以選。






















有上一個例子後,你應該會知道這三個改了之後大概會有什麼樣的效果。

此時,假設我們想要在螢幕高度1/3的位置處,往下畫出這個View,該怎麼做呢?

你可以先拉出一個View,讓他的高度等於1/3,確認你的位置是正確的。






















接著回到一開始拉出的置中View,並將Center Y的First Item改為Top,因為你要從1/3的位置處畫出這個View,而不是在1/3位置處置中這個View。

此時,你可以設定Second Item,預設是Superview.Center.Y,也就是在SuperView的置中的位置,一樣有數個選項可以做設定。

改到Top的話,就是在Superview的Top處。











而Superview的Bottom的話,你的View會在Superview的Bottom,

此時應該會在螢幕之外。











接著試著將Multiplier 改為1:3,你會看到你的View突然跑到螢幕之中。















可是還是有一點差異,因為有status bar的關係,因此會有一些差距。

你可以將status bar關閉,在將Frame修正,就會一致了。

此時你會看到你的View的確是在1/3處。
















或者你需要status bar的話,就只要將他的高度加入Constant之中即可。

status bar的高度為20,將他填入Constant之中。



















學會這個技巧後,許多需要透明View來達成的工作,也可以靠這樣的技巧來完成。

當然左右也是一樣的道理,靠比例來設定你需要的Layout吧!

2016年2月18日 星期四

[iOS] AutoLayout - 實際例子 - 圖片上放元件

有網友提出了這樣的問題,有一張圖在背景,會隨著螢幕比例不同而改變,而要怎麼準確的將元件放到正確的位置上呢?

首先你要先確認原圖的大小,並先將圖片放到正確的位置上。

畢竟,如果圖的位置都錯了,那調整元件也沒有任何意義。

圖片原始的大小是1024 x 158,在所有橫向的畫面上,至底。

首先先將StoryBoard調整成wAny hCompact

這樣我們可以只在橫向的iPhone顯示圖片。






















接著將ImageView加入其中,並設定左下右均為0,且將Aspect Ratio打勾。























接著我們將Aspect Ratio的比例設定一下,跟原圖要一樣的比例。



























此時你可以開各個模擬器並看一下效果是否正確。















確定圖片位置正確後,就可以開始將元件放在上面。

接著你得回去確認原始圖,你要放的位置是在哪兒。

首先先將下面的區塊標示出來吧,實際去量高度大約是42,那我們該怎麼標出下面的區塊呢?

先放一個View,左右下均為0,高為該ImageView的42/158

因為原始圖的全部高度為158,而原始圖該位置的高度為42,用比例的話他會自動縮放。













































做完這兩步驟你應該可以準確地畫出下半部的位置,接著我們是要在下半部的右邊。

因此我們可以在這個區塊再加入一個View,讓他靠右,寬度是這區塊的一半。











































此時你應該可以標出右邊的區塊了,接著我們量一下要放的位置是哪兒。

差不多是由左到右145距離左右,因此我們再塞入一個View,把145這個距離標出來。

首先一樣靠左上下均為0。

而寬你必須指定為supView的145/512,一樣得使用比例來決定他的寬。


























































此時你可以將一些View的底色改為透明,並且確認一下這個位置是不是正確的。











看起來是滿像我們要的效果,接著我們一樣把右邊的區塊顯示出來。

只需要加入一個左右上下均為0的View即可。



















接著我們只要在右邊的區塊加入我們要的View就可以了。

假設寬要320,而高要20,當然如果要設定也是要靠比例來設定。

首先先加入一個View,並且往左靠0




















接著將他的寬高設為與supview同寬高,在進行微調。



































當然別忘記置中也要設定。

















將高設為20:42






















將寬設為320:367























要隨時注意你的superView現在是多大來做改變。

寬367是因為左邊區塊是145,而512-145=367。

最後如果沒設定錯誤的話,應該會達到你所需要的效果。

將不必要的部份設為透明,只留下需要的部份。



















簡單的說可以運用比例與透明View來調整成你要的位置。

原圖的位置是相當重要的參考點,因為他會隨著你的螢幕大小而改變,

可以利用原圖的比例來設定,這樣不管在哪個狀況下都會改變。