February 24, 2012

การขยายรูปโดยไม่ให้ผิดสัดส่วนบริเวณขอบ

UIImage เป็นคลาสคลาสนึงที่มี API เปลี่ยนแปลงไปใน iOS 5 ทำให้มีบาง method ถูก Deprecate ไป แต่ก็มีบาง method ถูกเพิ่มเข้ามาใหม่ เช่น resizableImageWithCapInsets:

หากเรามีรูปแบบนี้อยู่



รูปนี้เราอาจจะเอามาใช้เป็นปุ่ม หรือ background ของอะไรบางอย่าง เวลาเรามาเอาใช้เป็น background ที่มีขนาดเดียวกับภาพก็จะไม่เป็นปัญหา แต่เมื่อนำมาใช้กับพื้นที่ที่ใหญ่กว่ารูปนี้ ปัญหาจะเกิดกับ Designer ทันที ที่เราต้องบอกให้ designer แก้รูปให้ใหม่ เพราะถ้าไม่แก้ จากโค้ดด้านล่าง


UIImage *image = [UIImage imageNamed: @"myButton.png"];    
UIImageView *imageView = [[UIImageView alloc] initWithImage: image];
imageView.frame = CGRectMake(20, 20, 250, 44);
imageView.contentMode = UIViewContentModeScaleToFill;
[self.view addSubview: imageView];


รูปต้นแบบมี resolution จริงๆ อยู่ที่ 80x44 เท่านั้น แต่เวลาเอามาใช้งานกลับนำมาใช้กับพื้นที่ขนาดใหญ่ถึง 250x44 ทำให้รูปมันยืดอย่างที่เห็นด้านล่าง



เดือดร้อนถึง designer หรือเราเองที่ต้องแก้รูปใหม่ แต่ด้วย method resizableImageWithCapInsets:  ทำให้เราสามารถแก้ไขรูปเองได้เลย เพียงแค่ตอนสร้าง UIImage ให้กำหนดค่าบางอย่างตามไปด้วยแบบนี้


UIImage *image = [[UIImage imageNamed: @"myButton.png"]
                  resizableImageWithCapInsets: UIEdgeInsetsMake(0, 10, 0, 10)];


ผลลัพธ์ที่ออกมาก็จะเป็นแบบนี้


โดยพารามิเตอร์ของ method พระเอกตัวนี้มีตัวเดียว ก็คือ UIEdgeInsets นั่นเอง ส่วนค่าทั้ง 4 ตัวที่ใช้ตอนสร้าง UIEdgeInstes นั้น เค้านิยามไว้ใน reference ดังนี้


typedef struct {
    CGFloat top, left, bottom, right;
} UIEdgeInsets;


ค่าทั้ง 4 นั้นเป็นค่าของ ขอบด้านบน, ซ้าย, ล่าง และขวา เวลาเรากำหนดค่าเหล่านี้ ก็จะเป็นการกำหนดว่าให้ขอบด้านไหนบ้าง ที่ไม่ให้มีการยืดหด หรือถูกเปลี่ยนแปลงขนาดไป ดังนั้นจากตัวอย่างโค้ดก็คือการกำหนดให้ขอบด้านซ้าย และด้านขวาเข้ามาข้างละ 10 pixel ไม่ต้องยืดเพื่อรักษาสัดส่วนไว้นั่นเอง