블로그 이미지
매몰

모바일 어플리케이션 개발 1인 기업 고영진모바일입니다. 저와 함께 맛깔스러운 앱을 만들어 보아요~

Rss feed Tistory
개발/ios 2018.05.08 11:12

UIEdgeInsets 없이 UILabel에 여백 넣기

UILabel에 여백을 넣는 방법은 다양하다.

그 중 NSLayoutConstraint를 이용하는 법을 다뤄보자!






class FitLabel: UILabel {


    //상하좌우 여백 storyboard 입력값

    @IBInspectable var edge: CGSize = CGSize(width: 0, height: 0)

    

    //너비, 높이가 적용될 Constraint

    private var mWidthConstraint, mHeightConstraint: NSLayoutConstraint?

    

    //좌우 여백값

    var edgeAllWidth: CGFloat {

        return edge.width * 2

    }

    

    //상하 여백값

    var edgeAllHeight: CGFloat {

        return edge.height * 2

    }

    

    override func awakeFromNib() {

        super.awakeFromNib()

        

        //storyboard에서 초기화된 글자로 맞춤

        fit()

    }


    func set(fitText text: String) {

        //코드상에서 글자를 직접 넣어 맞춤

        self.text = text

        fit()

    }

    

    private func fit() {

        //글자 + 여백 크기

        let width = intrinsicContentSize.width + edgeAllWidth

        let height = intrinsicContentSize.height + edgeAllHeight


        if mWidthConstraint == nil && mHeightConstraint == nil {

            //첫 실행때만 Constraint를 추가

            

            //Constraint를 직접 추가하기 위해 오토사이징 끔

            translatesAutoresizingMaskIntoConstraints = false

            

            //위의 글자 + 여백 크기를 너비,높이 Constraint로 생성하고 추가

            let widthConstraint = NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: width)

            let heightConstraint = NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: height)

            addConstraint(widthConstraint)

            addConstraint(heightConstraint)

            mWidthConstraint = widthConstraint

            mHeightConstraint = heightConstraint

        }

        else {

            //두번째부터는 Constraint의 수치만 변경

            mWidthConstraint!.constant = width

            mHeightConstraint!.constant = height

        }

        

        //중앙 정렬

        textAlignment = .center

    }

}




핵심 원리는 그저 글자 전체크기를 불러와 여백을 더하여 NSLayoutConstraint를 만드는 것이다.

너무 간단해서 더이상 설명이 필요없다ㅎㅎ


 

 



수제 앱 장인: 고영진


(주)고영진모바일

1인기업 대표이사 겸 개발자

  

     실패만 하고 있어도 꿈을 포기하지 않는 남자 

     제가 직접 경험하고 습득한 지식을 위주로 올릴게요

 






사업자 정보 표시
고영진모바일 | 고영진 | 서울특별시 관악구 낙성대동 서울대연구공원 SK상생혁신센터 | 사업자 등록번호 : 109-11-82076 | TEL : 010-9990-3674 | Mail : gyjmeba@hanmail.net | 통신판매신고번호 : 2010-서울강서-0217호 | 사이버몰의 이용약관 바로가기
개발/ios 2018.03.26 10:42

손쉽게 아이폰 앱을 새로 실행 시키는 코드 한줄



안드로이드에서는 메인 activity를 종료하고 다시 호출하면 바로 재시작이 된다.


하지만 아이폰에서는 그렇게 할수가 없었다. 혹시나 하는 마음에 재시작 시키는 함수를 찾아봤지만 이 또한 없었다. 나의 구글링 실력이 부족해서 못찾은거일수도 있지만... 좌절하고 있는 순간...


정말 우연하게 방법을 알아냈다. 사실 실수로 코드를 잘못 넣었는데... 재시작이 되는것이다... 아! 실수로 찍은 로또나 될것이지.. 어쨋든 기분은 좋다. 불로소득같은 느낌이다.



방법은 진짜 간단하다.

AppDelegate 의 applicationWillEnterForeground 에서 exit(0)를 호출해주면 된다.

아마도 잠에서 깨어나기 직전에 종료를 해주면 깨어나는 작업이 중단되지 않고 계속 진행되면서 재시작되는 효과가 나오는것 같다.


단점은 내가 원하는 시점이 아니라 앱이 깨어나는 순간에서만 적용된다는 것이다.

하지만 이는 아주 유용하게 쓰일수 있다.


iOS 특성상 앱을 완전 종료하지 않고 임시로 백그라운드로 내렸다가 다시 불려오는 경우가 많다.

(폰 아래 버튼은 종료 버튼이 아니라 홈 버튼이기 때문에)

즉, 앱이 완전 종료되고 다시 실행되어야만 하는 경우 매우 기특하게 사용될수 있다.



다음은 1시간 동안 앱이 포어그라운드로 깨어나지 않았다면 새로 실행 시키는 코드이다.

참고하여 다양하게 사용하길 바란다.



class AppDelegate: UIResponder, UIApplicationDelegate {


    let RESTART_TIME: TimeInterval = 3600

  

    var mResignTime: TimeInterval?


    func applicationWillResignActive(_ application: UIApplication) {

        mResignTime = NSDate().timeIntervalSince1970

    }


    func applicationWillEnterForeground(_ application: UIApplication) {

        if mResignTime != nil && NSDate().timeIntervalSince1970 - mResignTime! > RESTART_TIME {

            exit(0)

        }


    }

}



아이폰X와 아이폰7 (11.2)에서 테스트 해보았다. 잘 돌아간다. 굳!



 

 



수제 앱 장인: 고영진


(주)고영진모바일

1인기업 대표이사 겸 개발자

  

     실패만 하고 있어도 꿈을 포기하지 않는 남자 

     제가 직접 경험하고 습득한 지식을 위주로 올릴게요

 




사업자 정보 표시
고영진모바일 | 고영진 | 서울특별시 관악구 낙성대동 서울대연구공원 SK상생혁신센터 | 사업자 등록번호 : 109-11-82076 | TEL : 010-9990-3674 | Mail : gyjmeba@hanmail.net | 통신판매신고번호 : 2010-서울강서-0217호 | 사이버몰의 이용약관 바로가기
개발/ios 2017.11.20 11:45

NSString을 마치 UILabel인 양 사용하기

UILabel을 추가하면 간단하게 글자를 넣을 수 있다.

하지만 sub view가 많아지면 어플이 무거워 질 수 있는데 이럴때에는 NSString을 써주면 좋다.


그렇다면 NSString를 UILabel처럼 배경색을 넣어서 마치 view인듯 사용해 보자~


 


먼저, NSString이 들어있는 클래스를 하나 만들자! NSString를 상속받아 확장해도 좋다. 나는 그냥 했다. TextBox라고 명명하겠다.


class TextBox {

    

    //정렬키 상수

    static let CENTER = 0

    static let LEFT = 8

    static let RIGHT = 16

    static let TOP = 1

    static let BOTTOM = 2

    

    var mText: NSString

    var mAlign: Int

    var mFontAttrDic: [String: NSObject]

    var mRect, mBgRect: CGRect

    var mPadding: (left: CGFloat, top: CGFloat, right: CGFloat, bottom: CGFloat)

    var mBgColor: UIColor

    var mCornerRadius: CGFloat

    

    init(text: NSString, align: Int, padding: (left: CGFloat, top: CGFloat, right: CGFloat, bottom: CGFloat), font: UIFont, color: UIColor, bgColor: UIColor, corner: CGFloat = 0) {

        mText = text

        mAlign = align  //정렬

        mFontAttrDic = [

            NSForegroundColorAttributeName: color,

            NSParagraphStyleAttributeName: NSMutableParagraphStyle(),

            NSFontAttributeName: font

        ]

        mRect = CGRect()    //글자 위치크기

        mBgRect = CGRect()  //배경 위치크기

        mPadding = padding  //글자와배경 간격

        mBgColor = bgColor  //배경색

        mCornerRadius = corner //둥근사각형 각크기

    }

    

    func setPoint(x: CGFloat, _ y: CGFloat) -> TextBox {

        //글자 원본크기

        let size = mText.sizeWithAttributes(mFontAttrDic)

        let width = size.width

        let height = size.height

        

        //크기 설정

        let padding = mPadding

        mRect.size.width = width

        mRect.size.height = height

        mBgRect.size.width = width + padding.left + padding.right

        mBgRect.size.height = height + padding.top + padding.bottom

        

        //위치 설정

        //가로 정렬

        switch mAlign >> 3 {

        case 1: //왼쪽 정렬

            mRect.origin.x = x + padding.left

            mBgRect.origin.x = x

            

        case 2: //오른쪽 정렬

            let x = x - padding.right - width

            mRect.origin.x = x

            mBgRect.origin.x = x - padding.left

            

        default:    //가운데 정렬

            let x = x - (width / 2)

            mRect.origin.x = x

            mBgRect.origin.x = x - padding.left

        }

        

        //세로 정렬

        switch mAlign & 7 {

        case 1: //위쪽 정렬

            mRect.origin.y = y + padding.top

            mBgRect.origin.y = y

            

        case 2: //아래쪽 정렬

            let y = y - padding.bottom - height

            mRect.origin.x = y

            mBgRect.origin.x = y - padding.top

            

        default:    //가운데 정렬

            let y = y - (height / 2)

            mRect.origin.y = y

            mBgRect.origin.y = y - padding.top

        }

        

        return self

    }

    

    func draw(context: CGContext) {

        //배경 출력

        CGContextSetFillColorWithColor(context, mBgColor.CGColor)

        

        if mCornerRadius == 0 {

            //사각형

            CGContextFillRect(context, mBgRect)

        }

        else {

            //둥근사각형

            CGContextAddPath(context, UIBezierPath(roundedRect: mBgRect, byRoundingCorners: .AllCorners, cornerRadii: CGSizeMake(mCornerRadius, mCornerRadius)).CGPath)

            CGContextFillPath(context)

        }

        

        //글자 출력

        mText.drawInRect(mRect, withAttributes: mFontAttrDic)

    }

}


위의 소스를 보면 알겠지만 미리 색이나 글자배경 간격등을 정해준 후 setPoint로 위치를 찍어주면 글자크기를 얻어 배경을 설정값에 맞게 만들어주고 draw로 그려준다.




자.. UIView를 확장하여 위의 TextBox를 이용해 보자


class TextBoxsView: UIView {


    var mTextBoxs: [TextBox]!

    

    func initTextBoxs() {

        //폰트

        let font = UIFont.systemFontOfSize(15)

        

        mTextBoxs = [TextBox]()

        

        //사각형 배경

        mTextBoxs.append(TextBox(text: "Rect", align: TextBox.CENTER, padding: (30, 50, 40, 10), font: font, color: UIColor.whiteColor(), bgColor: UIColor.blackColor()).setPoint(100, 200))

        

        //둥근사각형 배경

        mTextBoxs.append(TextBox(text: "RoundRect", align: TextBox.LEFT, padding: (30, 30, 30, 30), font: font, color: UIColor.greenColor(), bgColor: UIColor.blueColor(), corner: 10).setPoint(100, 400))

    }

    

    override func drawRect(rect: CGRect) {

        let context = UIGraphicsGetCurrentContext()

        

        //출력

        for textBox in mTextBoxs {

            textBox.draw(context!)

        }

    }

}


테스트를 위해 설정값이 틀린 사각형과 둥근사각형 둘을 만들었다. initTextBoxs를 호출하면 된다.




끝으로 ViewController에서 view를 위의 TextBoxsView로 바꾸고 호출한다.


class TextBoxViewController: ViewController {

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        (view as! TextBoxsView).initTextBoxs()

    }

}





결과♡





 

 



수제 앱 장인: 고영진


(주)고영진모바일

1인기업 대표이사 겸 개발자

  

     실패만 하고 있어도 꿈을 포기하지 않는 남자 

     제가 직접 경험하고 습득한 지식을 위주로 올릴게요

 




사업자 정보 표시
고영진모바일 | 고영진 | 서울특별시 관악구 낙성대동 서울대연구공원 SK상생혁신센터 | 사업자 등록번호 : 109-11-82076 | TEL : 010-9990-3674 | Mail : gyjmeba@hanmail.net | 통신판매신고번호 : 2010-서울강서-0217호 | 사이버몰의 이용약관 바로가기
개발/ios 2017.04.25 10:43

UIView에 동적으로 버튼을 넣을때 크기를 같게 맞출려면?

안드로이드에서는 layout_weight 로 쉽게 하위 뷰들의 크기를 맞출 수 있다


예를 들어 버튼을 넣는다면 버튼에 layout_weight=1 속성을 추가한 후 

LinearLayout에 넣기만 하면 된다

또한 버튼 사이 간격은 layout_margin 로 조절한다


그렇다면 iso의 swift에선 어떻게 하면 될까?

약간 손이 더 가긴 하지만 어렵지 않다





편하게 사용하기 위해 UIView를 커스텀해서 만들어 보았다

버튼 크기를 맞춰주는 동시에 사이 간격, 여백도 줄것이다




class ButtonsView: UIView {

    

    private var mGap: CGFloat!

    private var mPadding: (left: CGFloat, top: CGFloat, right: CGFloat, bottom: CGFloat)!

    

    var mDelegate: ButtonsViewDelegate?

    

    //버튼간의 공간과 여백을 설정한다

    func setPadding(gap: CGFloat?, left: CGFloat, top: CGFloat, right: CGFloat, bottom: CGFloat) {

        //버튼간의 공간

        mGap = gap

        

        //여백

        mPadding = (left, top, right, bottom)

    }

    

    //버튼을 추가한다

    func addButton(name: String, color: CGColor) {

        //버튼을 생성한다

        let view = UIButton()

        

        //Autoresize 끈다

        //왜냐하면 우리는 직접 Constraint 설정해주기 때문이다

        view.translatesAutoresizingMaskIntoConstraints = false

        view.setTitle(name, forState: .Normal)

        view.layer.backgroundColor = color

        view.layer.cornerRadius = 5

        

        let count = subviews.count

        let padding = mPadding

        

        if count == 0 {

            //첫번째 버튼은 부모뷰와 맞게하고 그저 여백만 준다

            

            //부모뷰에 버튼을 추가한다

            addSubview(view)

            

            //부모뷰와의 상위 여백을 만든다

            addConstraint(NSLayoutConstraint(item: view, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1, constant: padding!.top))

            

            //부모뷰와의 하위 여백을 만든다

            addConstraint(NSLayoutConstraint(item: view, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1, constant: -padding!.bottom))

            

            //부모뷰와의 왼쪽 여백을 만든다

            addConstraint(NSLayoutConstraint(item: view, attribute: .Leading, relatedBy: .Equal, toItem: self, attribute: .Leading, multiplier: 1, constant: padding!.left))

            

            //부모뷰와의 오른쪽 여백을 만든다

            addConstraint(NSLayoutConstraint(item: view, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: 1, constant: -padding!.right))

        }

        else {

            //두번째 버튼부터는 첫번째 버튼과 같은 크기로 하고, 사이를 설정해 값으로 띄운다

            

            //부모뷰에 버튼을 추가하기 전에 첫번째, 마지막 버튼과 마지막 constraint 가져온다

            let firstView = subviews.first

            let lastView = subviews.last

            let lastConstraint = constraints.last

            

            //부모뷰에 버튼을 추가한다

            addSubview(view)

            

            //첫번째 버튼과 같은 크기로 만든다

            //, 버튼들이 늘어난 버튼 갯수만큼 작아지면서 같아진다

            addConstraint(NSLayoutConstraint(item: view, attribute: .Width, relatedBy: .Equal, toItem: firstView, attribute: .Width, multiplier: 1, constant: 0))

            

            //첫번째 버튼과 상위를 맞춘다

            addConstraint(NSLayoutConstraint(item: view, attribute: .Top, relatedBy: .Equal, toItem: firstView, attribute: .Top, multiplier: 1, constant: 0))

            

            //첫번째 버튼과 하위를 맞춘다

            addConstraint(NSLayoutConstraint(item: view, attribute: .Bottom, relatedBy: .Equal, toItem: firstView, attribute: .Bottom, multiplier: 1, constant: 0))

            

            //이전 버튼과 사이를 띄운다

            addConstraint(NSLayoutConstraint(item: view, attribute: .Leading, relatedBy: .Equal, toItem: lastView, attribute: .Trailing, multiplier: 1, constant: mGap!))

            

            //마지막 constraint , 이전 버튼의 오른쪽 여백을 제거한다

            removeConstraint(lastConstraint!)

            

            //현재 버튼으로 다시 오른쪽 여백을 만든다

            addConstraint(NSLayoutConstraint(item: view, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: 1, constant: -padding!.right))

        }

        

        //클릭 이벤트를 잡는다

        view.addTarget(self, action: "clickDetected:", forControlEvents: .TouchUpInside)

    }

    

    //모든 버튼을 제거한다

    func removeAllButtons() {

        for view in subviews {

            view.removeFromSuperview()

        }

    }

    

    //클릭 이벤트를 보낸다

    func clickDetected(sender: UIButton) {

        if mDelegate != nil {

            //클릭 이벤트의 전달 변수로 버튼 객체와 버튼 인덱스 번호를 보낸다

            mDelegate?.clickButtonsDetected(sender, position: subviews.indexOf(sender)!)

        }

    }

}


//클릭 이벤트를 보내기 위한 델리게이트

protocol ButtonsViewDelegate {

    func clickButtonsDetected(sender: UIButton, position: Int)

}







보통 이런 방식은 탭으로 많이 사용된다

탭 버튼으로 적용해 보자


먼저 스토리보드에서 화면을 다음과 같이 구성한다.

위의 푸른색 Add 와 clear 버튼은 각각 탭버튼 추가가 탭버튼 모두 삭제 기능을 갖는다

중간의 검정색 Name 과 Position 라벨은 탭버튼 이름과 번호를 표시한다.

끝으로 가장 아래의 회색 공간은 위에서 만든 buttonsView이다. 이곳에 탭버튼이 나타날것이다 









뷰컨트롤러이다

위에서 만든 프로토콜 델리게이션을 추가하고 처음에 탭버튼 3개를 만들어 놓는다

추가, 제거 버튼 및 탭버튼 클릭 함수도 등록한다




class ViewController: UIViewController, ButtonsViewDelegate {


    @IBOutlet var tabView: ButtonsView!

    @IBOutlet var buttonLabel: UILabel!

    @IBOutlet var positionLabel: UILabel!

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        //delegate 설정

        tabView.mDelegate = self

        

        //버튼 설정 생성

        tabView.setPadding(10, left: 10, top: 10, right: 10, bottom: 10)

        tabView.addButton("버튼1", color: UIColor.blueColor().CGColor)

        tabView.addButton("버튼2", color: UIColor.redColor().CGColor)

        tabView.addButton("버튼3", color: UIColor.greenColor().CGColor)

    }


    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        

    }


    @IBAction func clickAddDetected(sender: AnyObject) {

        //버튼 추가

        tabView.addButton("new", color: UIColor.brownColor().CGColor)

    }

    

    @IBAction func clickClearDetected(sender: AnyObject) {

        //모든 버튼 제거

        tabView.removeAllButtons()

    }

    

    func clickButtonsDetected(sender: UIButton, position: Int) {

        //버튼 출력

        buttonLabel.text = sender.titleLabel?.text

        positionLabel.text = "p: \(position)"

    }

}






실행해 보자







 

 



수제 앱 장인: 고영진


고영진모바일 1인기업 대표 겸 개발자 

  

     실패만 하고 있어도 꿈을 포기하지 않는 남자 

     제가 직접 경험하고 습득한 지식을 위주로 올릴게요

 



사업자 정보 표시
고영진모바일 | 고영진 | 서울특별시 관악구 낙성대동 서울대연구공원 SK상생혁신센터 | 사업자 등록번호 : 109-11-82076 | TEL : 010-9990-3674 | Mail : gyjmeba@hanmail.net | 통신판매신고번호 : 2010-서울강서-0217호 | 사이버몰의 이용약관 바로가기
개발/ios 2017.03.21 19:18

기준점을 중앙으로 Scale UIView 애니메이션 하기

swift 에서는 간단하게 뷰 애니메이션을 구현할 수 있다.


그런데 크기를 변경시키는 애니메이션에서는 주의 해야 할 점이 있다

바로 기준점이다



다음을 보자



let width = frame.width

let height = frame.height

        

frame.size.width = width * 0.2

frame.size.height = height * 0.2

        

UIView.animateWithDuration(1, delay: 0, options: [.CurveEaseInOut], animations: {

      self.frame.size.width = width

      self.frame.size.height = height

            

}, completion: nil)



20% 작은 크기에서 원래 크기로 애니메이션 효과를 주었다




기준점이 0이 되어 버렸다. 당연한 결과이다.

하지만 보통 중앙을 기준으로 할때가 많지 않은가?


이렇게 바꿔보자



let x = frame.origin.x

let y = frame.origin.y

let width = frame.width

let height = frame.height

        

frame.origin.x = x + ((width * 0.8) / 2)

frame.origin.y = y + ((height * 0.8) / 2)

frame.size.width = width * 0.2

frame.size.height = height * 0.2

        

UIView.animateWithDuration(1, delay: 0, options: [.CurveEaseInOut], animations: {

     self.frame.origin.x = x

     self.frame.origin.y = y

     self.frame.size.width = width

     self.frame.size.height = height

            

}, completion: nil)



X,Y 좌표를 100 - 20 = 80%의 반으로 옮긴 후 원래 위치로 애니메이션을 하였다




기준점이 중앙이 되었다. 

이런 방식으로 위치도 같이 변경해 주면 다양한 기준점으로 애니메이션 해줄 수 있다.



 

 



수제 앱 장인: 고영진


고영진모바일 1인기업 대표 겸 개발자 

  

     실패만 하고 있어도 꿈을 포기하지 않는 남자 

     제가 직접 경험하고 습득한 지식을 위주로 올릴게요

 




사업자 정보 표시
고영진모바일 | 고영진 | 서울특별시 관악구 낙성대동 서울대연구공원 SK상생혁신센터 | 사업자 등록번호 : 109-11-82076 | TEL : 010-9990-3674 | Mail : gyjmeba@hanmail.net | 통신판매신고번호 : 2010-서울강서-0217호 | 사이버몰의 이용약관 바로가기
개발/ios 2016.12.19 10:45

쿼츠2D로 자유롭게 폰트 크기를 바꿔보자



직접  UIView를 상속해서 자신만의 UI객체를 만들때 쿼츠 2D를 사용한다

이때, 폰트 크기는 어떻게 바꿀수 있을까?


NSString를 이용하면 간단하다.



class MyView: UIView {

    

    var mFontAttrDic: [String: NSObject]!

    var mFont: UIFont!

    var mText: NSString!

    

    override func drawRect(rect: CGRect) {

        //문자 출력

        mText.drawInRect(CGRectMake(0, 0, 100, 100), withAttributes: mFontAttrDic)

    }

    

    func intiFont() {

        //NSString 설정

        mText = "테스트"

        

        //폰트 설정

        mFont = UIFont(name: "SeoulNamsan CM", size: 10)!

        

        //NSString attribute 배열 설정

        mFontAttrDic = [

            NSForegroundColorAttributeName: UIColor.blackColor(),

            NSParagraphStyleAttributeName: NSMutableParagraphStyle(),

            NSFontAttributeName: mFont

        ]

    }

    

    func changeFontSize(size: CGFloat) {

        //폰트 사이즈를 변경하여 arriribute 배열 적용

        mFontAttrDic[NSFontAttributeName] = mFont.fontWithSize(size)

        

        //화면 갱신

        setNeedsDisplay()

    }

}




사용해 보자


let myView = MyView(frame: frame)

myView.initFont()


//폰트 크기를 바꾸고 싶을때 호출

myView.changeFontSize(20)





 

 



수제 앱 장인: 고영진


고영진모바일 1인기업 대표 겸 개발자 

  

     실패만 하고 있어도 꿈을 포기하지 않는 남자 

     제가 직접 경험하고 습득한 지식을 위주로 올릴게요

 



사업자 정보 표시
고영진모바일 | 고영진 | 서울특별시 관악구 낙성대동 서울대연구공원 SK상생혁신센터 | 사업자 등록번호 : 109-11-82076 | TEL : 010-9990-3674 | Mail : gyjmeba@hanmail.net | 통신판매신고번호 : 2010-서울강서-0217호 | 사이버몰의 이용약관 바로가기
TOTAL 69,581 TODAY 10