【问题标题】:How to create parent object for subview with multiple UIImageViews in ViewController using iOS5如何使用 iOS5 在 ViewController 中为具有多个 UIImageViews 的子视图创建父对象
【发布时间】:2012-03-22 12:36:26
【问题描述】:

在 iOS5 的 iPhone 应用程序中,我试图创建一个控制器对象,该对象包含一个带有多个 UIImageViews 的图像子视图。我有一个主视图控制器及其关联的主视图,在这个主视图中我有一个多图像子视图,这个子视图有十几个或更多 UIImageViews,如在 Interface Builder 中配置的那样。我创建了 UIView 的后代并将其连接为我的 ViewController 中 ImageSubView 的 IBOutlet 连接。我想在我的 subView 类中为十几个 UIImageViews 创建 IBOutlets,但 Interface Builder 只会让我在我的主 ViewController 中创建 IBOutlets,而不是在 ImageSubView 类中。那就是当我从 UIImageViews 之一控制拖动时,如果我在 MainViewController @interface 代码中拖动而不是 ImageSubView @interface 代码,它只会显示创建 IBOutlet。我希望从主 ViewController 中隐藏控制这十几个图像的细节。我希望主 ViewController 只与 ImageSubView 通信,并且 ImageSubView 知道如何操作其中的十几个图像。我需要创建一个子视图控制器吗?如果是这样,我如何在当前主视图中创建子视图控制器? Interface Builder 不允许我将另一个 ViewController 拖到当前主视图中。一个屏幕可以有多个viewController(一个主控制器和子控制器)吗?

视图层次结构如下所示:

MainViewController
    MainView
       ImageViewFullBackground
       ImageSubView
          UIImageView1
          UIImageView2
          . . . 
          UIImageView12
       Button1
       Button2
       . . .
       Button10

这里是我的 ImageSubView 标头,作为对 Allen 的回应。这个类其实叫UILedNumericView

//
//  UINumericLabel.h
//  UILedNumericView
//
//  Created by Jon D. Newbill on 2/18/12.
//  Copyright (c) 2012 Bitworks Systems Inc. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface UILedNumericView : UIView

@property (copy,nonatomic) NSString * text;

// This is the numeric value of the LED display as a double
@property (nonatomic) double value;

// Returns true if the numeric display contains a decimal point
@property (readonly,nonatomic) BOOL hasDecimalPoint;

// Returns true if numeric display contains an exponent
@property (readonly,nonatomic) BOOL hasExponent;

// Returns true if numeric display is equal to zero.
@property (readonly,nonatomic) BOOL isZero;

// Returns number of characters in entire display
@property (readonly,nonatomic) NSUInteger length;

// Returns zero based character index of the E in the display
@property (readonly,nonatomic) NSUInteger exponentIndex;

// Returns or sets mantissa portion of display.  This is everything
// preceding the "E" on the display or the entire display if it does
// not contain an "E";
@property (copy, nonatomic) NSString * mantissa;

// Returns or sets exponent portion of display.  This is everything
// following the "E" on the display.  If no E exists then an empty
// string is returned.  When set to a non-zero length string an E will
// be added to the display.
@property (copy, nonatomic) NSString * exponent;

// Returns maximum allowed characters in display
// This includes digits, sign, decimal point and exponent
+ (NSUInteger) maxLength;

@end

【问题讨论】:

  • 你能发布你的 ImageSubView.h 文件吗?

标签: iphone model-view-controller uiimageview subview iboutlet


【解决方案1】:

您可以从任何已经从 interfacebuilder 获得 IBOutlet 的视图中获取子视图,如下所示:

NSArray *subViewsArray = self.view.subviews; //Change this to the name of your view
UIView *view1 = [subViewsArray objectAtIndex:0]; //This selects view at position 0
NSLog(@"View1: %@",view1); //You can see what view you extracted (the properties)

您无需创建视图控制器或其他东西。但是,如果您愿意,这是可能的,但我不相信这是您想要的。

编辑:IBOutlets,顾名思义,用于告诉编译器在界面构建器中创建一个指向项目的指针,因此,如果您按照我发布的内容进行操作,您仍在以编程方式创建这些指针.如果您想像 IBOutlets 一样拥有这些“全局”便利,只需为 UIView 创建一个属性,而不是像我一样在本地声明它们。

Edit2:忘了说视图的顺序和界面构建器中从上到下的顺序是一样的。 (除非您以编程方式更改它们)

【讨论】:

  • 您的意思是在 Main 控件中为十几个 UIImageView 创建 IBOutlets,然后从子视图访问它们以在子视图中创建 UIImageView 数组吗?如果是这样,我知道我可以做到。但这将是一个相当糟糕的面向对象设计。目的是仅将十几个子 UIImageView 连接到子视图,这样视图控制器就无法看到子 UIImageView。或者你的意思是我不需要任何 IBOutlets 但可以通过它们在子视图和界面构建器中的视图层次结构中表示的十几个子图像之间的关系来访问图像?
  • 你不需要 IBOutlets,你只需要 1 个作为主要的。然后,如果您看到嵌套在 IB 构建器上的那些子视图,那么您可以像我在代码中解释的那样通过父视图访问它们
  • 谢谢!在 Paul Hegarty 的斯坦福 iPhone App 课程 (ITUnesU) 中,IBOutlets 非常重要,我没有意识到它们只需要连接 controllersviews。目前尚不清楚子视图之间的关系是否自动连接。这就是我缺少的一点。我试图将我的子视图连接到十几个子图像视图,但它们已经通过 subviews 属性连接并可用。作为第一个回答我的问题的人,我将 50 分奖励给你。
【解决方案2】:
   int i,x,y;
   x=y=2;
    NSArray *viewsToRemove = [mainScroll subviews];
      for (UIView *v in viewsToRemove) [v removeFromSuperview];

      useD=[NSUserDefaults standardUserDefaults];
      imageArray=[useD objectForKey:LIVE];
      for( i=1;i<=[imageArray count] ;i++)
      {   
          iName=[imageArray objectAtIndex:i-1];
          UIImage *image = [UIImage imageNamed:iName];
          UIImageView *mainImageView=[[UIImageView alloc]initWithImage:image];
          [mainImageView setTag:i];
          [mainImageView setUserInteractionEnabled:YES];

          //for delete time tap and general tap gesture
          if(tapFlag)
          {
              tap=[[UITapGestureRecognizer alloc]initWithTarget:self       action:@selector(imageDisplay:)];
              [mainImageView addGestureRecognizer:tap];
          }
          else
          {
              UITapGestureRecognizer *tap2=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(selection:)];
              [mainImageView addGestureRecognizer:tap2];
          }

          //for Border and lastAccessed Diff. Border
          if(lastAccessed==i)
          {
              [mainImageView.layer setBorderColor:[UIColor blueColor].CGColor];
              [mainImageView.layer setBorderWidth:2];
          }
          else
          {
              [mainImageView.layer setBorderColor:[UIColor whiteColor].CGColor];
              [mainImageView.layer setBorderWidth:2]; 
          }
          //for rounded UIImageView
          CALayer * l = [mainImageView layer];
          [l setMasksToBounds:YES];
          [l setCornerRadius:10.0];


          CGRect frame = CGRectMake(x,y,WIDTH,HEIGHT);
          mainImageView.frame = frame;


          x+=WIDTH;
          if(i%orientation==0)
          {
              x=2;
              y=y+HEIGHT+5;
          }
          else
          {
              x=x+GAP;
          }
          [mainScroll addSubview:mainImageView];

      }
      [mainScroll setContentSize:CGSizeMake(0,(i-1)*add)];
  }

【讨论】:

    【解决方案3】:

    首先:在 ImageSubView 标头中声明 IBOutlets(我想是 UILedNumericView.h)。每个 UIImageView 一个 第二:转到 Interface Builder 并确保将 ImageSubView 的类设置为 UILedNumericView,因为这是 ImageSubView 的类。 第三:控制从每个imageView#拖动到Interface Builder左侧的ImageSubView(带有视图树的示意图)。 第四:出现 IBOutlets 列表并选择正确的。 第五:在UILedNumericView.m中合成所有的IBOutlets并编写一些方法来管理它们

    如果我理解了你的问题,那就是显而易见的解决方案。

    第三次可以通过选择 ImageSubView 并从右侧面板中完成,您可以在右侧面板中获得所选对象出口的完整列表,并且可以从它们拖动到 imageViews。

    【讨论】:

      【解决方案4】:

      您为什么不简单地将您的 ImageSubView 设计为一个单独的 UIView。在它自己的 .xib 文件中布局该子视图。然后确保您的子类实现initWithCoder:。然后您可以将子视图添加到您的 ImageViewController。只需确保 .xib 中的所有对象都定义了它们的自定义类。

      如果有一些图片或示例项目可以帮助您更深入地理解这个概念,请告诉我。有时候IB在幕后所做的工作看起来很神奇,但一旦你了解它,你就会看到它背后的强大力量。

      【讨论】:

      • 我是在IOS5开始开发的,对XIB文件不熟悉。我认为 Storyboards 取代了 XIB。是否有需要 XIB 的 Storyboard 无法完成的事情?是的,进一步的解释会有所帮助。我对 initWithCoder 的解读是它实现了一种用于归档对象的序列化形式。不确定这在这里如何应用。我只想创建一个负责(封装)一组 imageView 的子对象,因此对于 ViewController,它看起来就像是一个对象。特别是它看起来像是由一组图像组成的数字显示。
      【解决方案5】:

      首先,如果您想将逻辑隐藏到不同于MainViewController 的对象中,我建议您创建第二个控制器,例如。 ImageSubViewController。您可以通过专用的 NIB 文件定义它的外观,在该文件中,您将所有 UIImageViews 链接到父 ImageSubViewController 及其 IBOutlets

      那么,我建议你这样做:

      1. 将通用的UIView 组件添加到MainViewController 的视图中,并添加一个IBOutlet 来处理它(我们称之为imageSubView
      2. MainViewController 添加一个属性来处理ImageSubViewController 的实例(我们称之为imageSubViewController
      3. MainViewController 内部,在viewDidLoad 方法中,实例化ImageSubViewController,然后将其视图添加到之前创建的占位符中:

        [self.imageSubView addSubView:imageSubViewController.view];

      这样您将在MainViewController 中拥有自定义子视图,并且您可以通过ImageSubViewController 实例控制其行为,甚至可以控制每个子图像视图出口,例如。通过imageSubViewController.image1imageSubViewController.image2等。

      我认为通过这种方式,您的解决方案会有一个很好的实现,主控制器和自定义子视图的行为之间有很好的解耦。让我知道这是否有帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-20
        • 1970-01-01
        • 2012-03-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多