我熟悉为我自己的UIView子类创建XIB的大部分过程,但并不是所有的东西都适合我 - 这主要与IBOutlets链接有关.我可以让它们以迂回的方式工作.
我的设置是这样的:
我的init方法是我遇到问题的地方.
我尝试使用NSBundle mainBundle的'loadNibNamed'方法并将所有者设置为'self',希望我创建一个视图实例,它会自动将它的出口与我班级的出口相匹配(我知道)怎么做,我很小心).然后我想我想让'self'等于那个nib中索引0的子视图,而不是做
self = [super init];
Run Code Online (Sandbox Code Playgroud)
或类似的东西.
我觉得我在这里做错了,但是在线的例子在init方法中有类似的事情,但他们将子视图0分配给view属性并将其作为子项添加 - 但是那不是总共两个MyClass实例?一个基本上与IBOutlets无关,包含通过loadNibNamed实例化的子MyClass?或者充其量,它不是一个MyClass实例,带有一个额外的中间UIView,其中包含我最初想要的所有IBOutlets作为MyClass的直接子项吗?当涉及到像instanceOfMyClass.frame.size.width这样的事情时,这会带来轻微的烦恼,因为它返回0,当引入的子UIView返回我正在寻找的实际帧大小时.
我在做错的是我在init方法中搞乱了loadNibNamed吗?我应该做更像这样的事情吗?
MyClass *instance = [[MyClass alloc] init];
[[NSBundle mainBundle] loadNibNamed:@"MyClass" owner:instance options:nil];
Run Code Online (Sandbox Code Playgroud)
或者像这样?
MyClass *instance = [[[NSBundle mainBundle] loadNibNamed:@"MyClass" owner:nil options:nil] objectAtIndex:0];
Run Code Online (Sandbox Code Playgroud)
在此先感谢您的任何帮助.
我知道这是非常直接的,但是经过太多的拉毛后,我无法解决问题.
我看过教程解释如何使用XIB和所有创建视图.但它们都没有解决我在这里的情况.
我有一个XIB文件,一个自定义的UIView子类,它有很少的标签和按钮.UIView子类是可重用的,这就是我不能在任何单个View控制器中安装插座的原因.因此,我将此视图的各个控件(子视图)存储在我的自定义UIView本身中.这是合乎逻辑的,因为没有视图控制器应该拥有此自定义视图的子视图,该视图将包含在每个视图控制器中.
问题是,我不知道如何完全初始化整个UI.
这是我的UIView子类的代码:
@interface MCPTGenericView : UIView
+(id)createInstance : (bool) bPortrait;
@property (weak, nonatomic) IBOutlet UIView *topView;
@property (weak, nonatomic) IBOutlet UIView *titleView;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UIButton *logoButton;
@property (weak, nonatomic) IBOutlet UITextField *searchTextField;
@property (weak, nonatomic) IBOutlet UIButton *menuButton;
@end
Run Code Online (Sandbox Code Playgroud)
后来,我也计划将这个相同的XIB文件用于这个UIView的横向,我计划在同一个XIB中使用相同的上面的出口和横向控制.
以下是实施:
@implementation MCPTGenericView
//@synthesize topView, titleLabel, titleView;
+(id)createInstance : (bool) bPortrait
{
UIView * topLevelView = nil;
MCPTGenericView * instance = [MCPTGenericView new];
NSArray * views = [[NSBundle mainBundle] …
Run Code Online (Sandbox Code Playgroud) 我正在尝试从笔尖加载视图,配置它并拍摄快照,而不将其添加到屏幕:
+ (void)composeFromNibWithImage:(UIImage*)catImage completion:(CompletionBlock)completion {
NSArray *nibContents = [[NSBundle mainBundle] loadNibNamed:@"CatNib" owner:nil options:nil];
CatView *catView = [nibContents firstObject];
//here, catView is the correct size from the nib, but is blank if inspected with the debugger
catView.catImageView.image = catImage;
catView.furButton.selected = YES;
UIImage *composite = [UIImage snapshot:catView];
completion(composite);
}
Run Code Online (Sandbox Code Playgroud)
快照是典型的:
+ (UIImage *)snapshot:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Run Code Online (Sandbox Code Playgroud)
但是,当我单步执行代码时,catView和composite都会正确调整大小但是空白.如何从一个从笔尖加载的视图创建UIImage,而不将视图添加到屏幕?
我想知道怎样loadNibNamed
的NSBundle
类作品; 在某些文件中我发现了类似的东西
[[NSBundle mainBundle] loadNibNamed:@"mynib" owner:self options:NULL];
Run Code Online (Sandbox Code Playgroud)
没有回报价值; 只是在方法内部调用(例如,cellForRowAtIndexPath
如果我想自定义我的单元格).在其他文件中我发现:
NSArray* vett=[[NSBundle mainBundle] loadNibNamed:@"mynib" owner:self options:NULL];
Run Code Online (Sandbox Code Playgroud)
在这种情况下,例如cellForRowAtIndexPath
,我可以
return [vett lastObject];
Run Code Online (Sandbox Code Playgroud)
或类似的东西.后一种方法在我看来很清楚; 我在一个向量中加载笔尖然后我使用向量元素.问题是要了解第一个究竟是做什么的:
[[NSBundle mainBundle] loadNibNamed:@"mynib" owner:self options:NULL];
Run Code Online (Sandbox Code Playgroud)
没有返回值,没有单元格引用...我的笔尖的对象在哪里?他们是如何处理的?我不明白它是如何工作的
我有一个viewcontroller,它包含许多自定义UIViews.自定义UIView我尝试使用InterfaceBuilder(IB)定义它,并使用以下代码将其加载到initWithFrame中:
NSArray *xib=[[NSBundle mainBundle] loadNibNamed:@"DayView" owner:self options:nil];
Run Code Online (Sandbox Code Playgroud)
视图控制器表现得非常慢,所以我决定尝试以编程方式加载自定义uiview的项目.Vòila,速度增加了约7倍.
加载XIB文件和使用"干净"代码之间的区别是如此之大?我可以想到的第一个假设是IB默认设置了很多属性,而在代码中定义它们时它们只是nil.但它无法解释巨大的性能差异!我没有发现任何明确警告你不要使用性能原因的IB的帖子.
编辑:我刚刚找到这个链接,因此这个博客文章解释了有关何时从光盘加载xib文件的有趣的事情.我想从光盘加载解释了差异./ K
道歉,因为我看到人们之前已经问过这样的问题了.但是,按照说明我没有太多运气.我有兴趣使用xib文件创建自定义视图,并在另一个视图控制器的xib文件中重用它.
现有职位:
我已经:
这会导致在构建应用程序时显示空白视图.
然后我尝试了上面的帖子之一所说的,它覆盖了CustomView的initWithDecoder方法并添加了以下内容:
NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil];
UIView *mainView = [subviewArray objectAtIndex:0];
[self addSubview:mainView];
Run Code Online (Sandbox Code Playgroud)
不幸的是,这导致了以下错误:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason:
'[<UIView 0x548ff00> setValue:forUndefinedKey:]:
Run Code Online (Sandbox Code Playgroud)
我认为这可能是因为我没有将CustomView.xib中的顶级视图设置为CustomView类.然后我将其更改为CustomView,然后事情进入无限递归.这是有道理的,因为它只是一遍又一遍地重新加载.
不确定我之前的帖子中遗漏了什么,但我很感激任何指导!谢谢!
对此问题提前道歉,尽管自iOS问世以来已经详细讨论过.但尽管我付出了最大的努力,但我仍然没有得到它.我可以拍摄的最接近的图像是"冻结和干燥的物体图形",这很好,但是当它归结为原始编程时,这无助于连接点.
因此,考虑到在找出问题之前你无法真正描述任何内容,让我们采用以下示例:
1)我有一个Xib文件,比如一个UIView,带有标签和imageView
2)我有一个来自UIView的classX,子类,它附加到IB的身份检查器中的Xib.IB连接和IB操作在连接检查器中连接到此类.此类将IB/IA声明为属性.
3)我有一个UIViewController,由classVC表示.在这个类中,我实例化1)使用标准[[NSBundle mainBundle] loadNibNamed:@"bla" owner:??? options:nil][0];
4)classX和classVC通过自定义委托,标准内容进行通信.
问题:
a)XIB文件的所有者是什么.老实说,我不知道.
b)我为主[[NSBundle mainBundle] loadNibNamed:@"bla" owner:??? options:nil][0];
人参数添加了什么,最重要的是,为什么?
当对象图解冻并浇水时,不应该运行时连接Outlets在2)中定义的那么在这种情况下文件所有者的重点是什么?
要么
如果XIB文件奥特莱斯没有连接到任何东西,没有"文件的所有者"的意思是"我是一个包含所有必需的网点,使得类的实例,并解压缩XIB之间的连接可以使类?(这就是为什么我不得到它,因为如何建立关联???)
就是这样了.就像以前一样愚蠢.
编辑:我不同意其他答案同样有效的事实.我理解他们的意思,但到目前为止,我还没有理解所有者参数对于我描述的情况应该具有什么,最重要的是,为什么.
Apple Doc说nib文件中最重要的对象之一是File的Owner对象,但它似乎是nib文件中的File所有者,而不是LoadNibName
方法设置的那个.我想知道它们之间的区别是什么?
这是一个例子:
我从xib自定义alertView并提供如下静态类方法:
+(CustomAlert *)sharedAlert{
CustomAlert *alert = [[[NSBundle mainBundle] loadNibNamed:@"CustomAlert" owner:nil options:nil]lastObject];
return alert;
}
Run Code Online (Sandbox Code Playgroud)
我有一种方法在视图上显示警报
- (void)showInView:(UIView *)view{
[view addSubview:self];
}
Run Code Online (Sandbox Code Playgroud)
在我的viewController中:
- (IBAction)buttonPressed:(id)sender{
CustomAlert *alert = [CustomAlert sharedAlert];
[alert showInView:self.view];
}
Run Code Online (Sandbox Code Playgroud)
它适用于我的情况,所以有必要设置所有者[[[NSBundle mainBundle] loadNibNamed: owner: options:
吗?
我创建了一个与.xib文件关联的UIView子类.这个UIView子类将在UIViewController中使用.在控制器中,我认为我们实例化UIView子类有两种选择:
MyUIView *myView=[[MyUIView alloc] initWithFrame:aRect];
Run Code Online (Sandbox Code Playgroud)
和
MyUIView *myView = [[[NSBundle mainBundle] loadNibNamed:@"MyUIView"
owner:self
options:nil] lastObject];
Run Code Online (Sandbox Code Playgroud)
我更喜欢允许我执行自定义初始化的第一种方法或其变体.唯一的问题是我必须指定一个框架的rect,它已经在中指定了.xib
(我的意思是框架的高度和宽度MyUIView
).是的,我能再次硬编码aRect
,但这是乏味的维护(例如,当我改变的.xib用户界面的位置,我需要更新aRect
,太).
所以第二种方法应该在脑架自动设置时考虑到.剩下的问题是我无法自定义初始化程序(比方说,我想在初始化期间传递额外的参数).
你有什么偏好?你认为哪一个更好?
编辑1:受塞尔吉奥的回答启发,我推出了这个解决方法:
// In MyViewController.m
MyUIView *myView=[[MyUIView alloc] initWithFrame:CGRectMake(x, y, 0.0, 0.0)];
// In MyView.m
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self = [[[NSBundle mainBundle] loadNibNamed:@"UnmovableTagView"
owner:self
options:nil] lastObject];
[self setFrame:CGRectMake(frame.origin.x,
frame.origin.y,
[self frame].size.width,
[self frame].size.height)];
// frame's width and height already determined after
// loadNibNamed was called
...
}
return self; …
Run Code Online (Sandbox Code Playgroud) uiview designated-initializer ios initwithframe loadnibnamed
ios ×9
loadnibnamed ×9
uiview ×4
objective-c ×3
iboutlet ×2
xib ×2
init ×1
iphone ×1
nsbundle ×1
object-graph ×1
performance ×1
uiimage ×1