UIView 하위 클래스의 Nib을 로드하는 올바른 방법
이 질문은 이전에 질문한 적이 있는 것으로 알고 있지만 답변이 상반되고 혼란스러우니 제발 저를 화나게 하지 말아주세요.
재사용 가능한 것을 갖고 싶습니다.UIView
서브클래스로 이동할 수 있습니다.nib 파일을 사용하여 인터페이스를 설명하고자 합니다.
이제 작업 지시자가 포함된 로딩 지시자 뷰라고 가정해 보겠습니다.이 보기를 인스턴스화하고 보기 컨트롤러 보기로 애니메이션화하는 이벤트를 하고 싶습니다.저는 뷰의 인터페이스를 프로그래밍 방식으로 설명할 수 있었습니다. 요소를 프로그래밍 방식으로 만들고 프레임을 init 방식으로 설정하는 등 말이죠.
근데 이거 어떻게 펜촉으로 하는 거예요?프레임을 설정할 필요 없이 인터페이스 빌더에 주어진 크기를 유지합니다.
저는 이 방법을 사용해 왔지만, 잘못된 것이라고 확신합니다. (이것은 단지 선택 도구가 있는 보기일 뿐입니다.
- (id)initWithDataSource:(NSDictionary *)dataSource {
self = [super init];
if (self){
self = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@", [self class]] owner:self options:nil] objectAtIndex:0];
self.pickerViewData = dataSource;
[self configurePickerView];
}
return self;
}
하지만 저는 자기 자신을 덮어쓰고 있습니다. 그리고 그것을 인스턴스화할 때:
FSASelectView *selectView = [[FSASelectView alloc] initWithDataSource:selectViewDictionary];
selectView.delegate = self;
selectView.frame = CGRectMake(0, self.view.bottom + 50, [FSASelectView width], [FSASelectView height]);
IB에서 프레임을 픽업하는 것보다 수작업으로 프레임을 설정해야 합니다.
편집: 뷰 컨트롤러에 이 사용자 지정 뷰를 만들고 뷰의 요소를 제어할 수 있는 액세스 권한을 가지려고 합니다.저는 새로운 뷰 컨트롤러를 원하지 않습니다.
감사해요.
편집: 이것이 최선의 방법인지는 모르겠지만, 분명 그렇지는 않지만, 제가 이렇게 한 방법은 이렇습니다.
FSASelectView *selectView = [[[NSBundle mainBundle] loadNibNamed:[NSString stringWithFormat:@"%@",[FSASelectView class]] owner:self options:nil] objectAtIndex:0];
selectView.delegate = self;
[selectView configurePickerViewWithData:ds];
selectView.frame = CGRectMake(0, self.view.bottom + 50, selectView.width, selectView.height);
selectView.alpha = 0.9;
[self.view addSubview:selectView];
[UIView animateWithDuration: 0.25 delay: 0 options:UIViewAnimationOptionAllowUserInteraction |UIViewAnimationOptionCurveEaseInOut animations:^{
selectView.frame = CGRectMake(0, self.view.bottom - selectView.height, selectView.width, selectView.height);
selectView.alpha = 1;
} completion:^(BOOL finished) {
}];
정확한 실습이 여전히 필요함
보기 컨트롤러를 사용하여 이 작업을 수행하고 nib 이름으로 init를 수행했어야 했습니까?코드의 UIView 초기화 방법으로 nib을 설정했어야 합니까?아니면 제가 한 일이 괜찮은가요?
MyViewClass *myViewObject = [[[NSBundle mainBundle] loadNibNamed:@"MyViewClassNib" owner:self options:nil] objectAtIndex:0]
재사용 가능한 사용자 지정 보기를 초기화하는 데 사용하고 있습니다.
여기서 마지막에 "first Object"를 사용하면 좀 더 깨끗합니다.NSray와 NSMutable Array에서 편리한 방법은 "first Object"입니다.
테이블 헤더로 사용할 xib를 로드하는 전형적인 예가 있습니다.당신의 파일에 당신의 클래스.m.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
return [[NSBundle mainBundle] loadNibNamed:@"TopArea" owner:self options:nil].firstObject;
}
에서.TopArea.xib
, File Owner(파일 소유자)를 클릭하고 파일 소유자를 Your Class(유어 클래스)로 설정합니다.그러면 실제로 YourClass.h에는 IBOUTlet 속성이 있습니다.TopArea.xib
, 제어 장치를 저 콘센트로 끌면 됩니다.
에서 그걸 TopArea.xib
, 보기 자체를 클릭하여 필요한 경우 해당 보기를 어느 콘센트로 끌어다 놓아야 할 수도 있습니다. (매우 가치 있는 팁은 테이블 셀 행에 대해 이 작업을 수행할 때 반드시 해당 작업을 수행해야 한다는 것입니다. 즉, 보기 자체를 코드의 관련 속성에 연결해야 한다는 것입니다.
당신이 당신의 것을 유지하고 싶다면.CustomView
그리고 그것의xib
과는 무관하게File's Owner
, 그런 다음 이 단계를 따릅니다.
- 나가세요
File's Owner
필드가 비어 있습니다. - 실제 보기 클릭
xib
너의 파일CustomView
그것을 설정합니다.Custom Class
~하듯이CustomView
(사용자 정의 보기 클래스 이름) - 더하다
IBOutlet
인에.h
사용자 정의 보기의 파일입니다. -
.xib
사용자 정의 보기의 파일, 보기를 클릭하고 들어가십시오.Connection Inspector
. 여기서 정의한 모든 IBOUTLET이 표시됩니다..h
파일 - 각각의 보기와 연결합니다.
인에.m
너의 파일CustomView
클래스, override theinit
방법은 다음과 같습니다.
-(CustomView *) init{
CustomView *result = nil;
NSArray* elements = [[NSBundle mainBundle] loadNibNamed: NSStringFromClass([self class]) owner:self options: nil];
for (id anObject in elements)
{
if ([anObject isKindOfClass:[self class]])
{
result = anObject;
break;
}
}
return result;
}
이제 당신이 당신의 짐을 싣고 싶을 때.CustomView
, 다음 줄의 코드를 사용합니다.[[CustomView alloc] init];
다음 단계를 따릅니다.
- MyView .h/.m .
UIView
. - 같은 이름의 xib 만들기
MyView.xib
. - 이제 파일 소유자 클래스를 다음으로 변경합니다.
UIViewController
부터NSObject
XIB로아래 이미지 참조 파일 소유자 보기를 보기에 연결합니다.아래 이미지 참조
보기 클래스를 다음으로 변경합니다.
MyView
랑 같아요 3과 같습니다.- 컨트롤 배치는 IBOUTlet을 만듭니다.
View를 로드하는 코드는 다음과 같습니다.
UIViewController *controller=[[UIViewController alloc] initWithNibName:@"MyView" bundle:nil];
MyView* view=(MyView*)controller.view;
[self.view addSubview:myview];
도움이 되길 바랍니다.
명확화:
UIViewController
xib 및 View를 로드하는 데 사용됩니다.UIViewController
하스는 사실MyView
MyView xib에 할당한 파일입니다.
데모 여기서 데모를 해봤습니다.
2년 후에 여기서 내 질문에 답하는 건...
프로토콜 확장자를 사용하기 때문에 모든 클래스에 별도의 코드 없이 할 수 있습니다.
/*
Prerequisites
-------------
- In IB set the view's class to the type hook up any IBOutlets
- In IB ensure the file's owner is blank
*/
public protocol CreatedFromNib {
static func createFromNib() -> Self?
static func nibName() -> String?
}
extension UIView: CreatedFromNib { }
public extension CreatedFromNib where Self: UIView {
public static func createFromNib() -> Self? {
guard let nibName = nibName() else { return nil }
guard let view = NSBundle.mainBundle().loadNibNamed(nibName, owner: nil, options: nil).last as? Self else { return nil }
return view
}
public static func nibName() -> String? {
guard let n = NSStringFromClass(Self.self).componentsSeparatedByString(".").last else { return nil }
return n
}
}
// Usage:
let myView = MyView().createFromNib()
스위프트에서:
예를 들어, 사용자 지정 클래스의 이름은InfoView
처음에는 파일을 만들고,InfoView.xib
그리고.InfoView.swift
다음과 같이:
import Foundation
import UIKit
class InfoView: UIView {
class func instanceFromNib() -> UIView {
return UINib(nibName: "InfoView", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as! UIView
}
그다음에File's Owner
.UIViewController
다음과 같이:
이름 바꾸기View
.InfoView
:
마우스 오른쪽 단추로 클릭File's Owner
그리고 당신의 것을 연결합니다.view
당신의 필드를 사용합니다.InfoView
:
클래스 이름이 다음과 같도록 합니다.InfoView
:
그런 다음 작업을 사용자 지정 클래스의 버튼에 문제 없이 추가할 수 있습니다.
그리고 이 커스텀 클래스의 용도는MainViewController
:
func someMethod() {
var v = InfoView.instanceFromNib()
v.frame = self.view.bounds
self.view.addSubview(v)
}
뷰 컨트롤러를 사용하여 xib를 초기화하고 viewController.view를 사용하거나 사용자가 수행한 방식으로 수행할 수 있습니다.새만 .UIView
하위 클래스를 컨트롤러로 지정합니다.UIView
나쁜 생각입니다.
사용자 정의 보기에서 콘센트가 없는 경우 직접 A를 사용할 수 있습니다.UIViewController
초기화할 클래스입니다.
업데이트: 사용자의 경우:
UIViewController *genericViewCon = [[UIViewController alloc] initWithNibName:@"CustomView"];
//Assuming you have a reference for the activity indicator in your custom view class
CustomView *myView = (CustomView *)genericViewCon.view;
[parentView addSubview:myView];
//And when necessary
[myView.activityIndicator startAnimating]; //or stop
그렇지 않으면 주문 제작을 해야 합니다.UIViewController
(출구가 적절하게 연결되도록 파일의 소유자로 만듭니다.)
YourCustomController *yCustCon = [[YourCustomController alloc] initWithNibName:@"YourXibName"].
원하는 위치에 사용할 수 있는 뷰를 추가할 수 있습니다.
[parentView addSubview:yCustCon.view];
그러나 xib를 로드하는 동안 다른 뷰 컨트롤러(이미 다른 뷰에 사용 중임)를 소유자로 전달하는 것은 컨트롤러의 뷰 속성이 변경되고 원래 뷰에 액세스하려는 경우 참조가 없기 때문에 좋지 않습니다.
편집: 파일 소유자와 동일한 메인으로 새 xib을 설정한 경우 이 문제가 발생합니다.UIViewController
클래스 및 뷰 속성을 새 xib 뷰에 연결했습니다.
즉,
- MainView Controller -- manages -- mainView
- CustomView - 필요한 경우 xibas에서 로드해야 합니다.
아래 코드는 나중에 혼동을 일으킬 것입니다. 만약 당신이 그것을 인사이드 뷰로 작성한다면 로드가 된 것입니다.YourMainViewController
. 그 이유는self.view
이 시점부터 사용자 정의 보기를 참조합니다.
-(void)viewDidLoad:(){
UIView *childView= [[[NSBundle mainBundle] loadNibNamed:@"YourXibName" owner:self options:nil] objectAtIndex:0];
}
언급URL : https://stackoverflow.com/questions/15405916/correct-way-to-load-a-nib-for-a-uiview-subclass
'programing' 카테고리의 다른 글
SQL 0(음의 값인 경우) (0) | 2023.10.18 |
---|---|
angularjs: ng-message가 항상 표시됨 (0) | 2023.10.18 |
angularjs로 ng가 아닌 다른 접두사를 사용해도 될까요? (0) | 2023.10.18 |
파일 크기 기준을 충족하기 위해 파일에 삽입할 특정 길이의 문자열을 생성하는 방법? (0) | 2023.10.18 |
자바스크립트에서 시간대 오프셋이 있는 날짜를 ISO 8601 형식으로 지정하는 방법은 무엇입니까? (0) | 2023.10.18 |