Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/113.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 目标C:全球方法文本领域_Ios_Iphone_Objective C_Storyboard_Textfield - Fatal编程技术网

Ios 目标C:全球方法文本领域

Ios 目标C:全球方法文本领域,ios,iphone,objective-c,storyboard,textfield,Ios,Iphone,Objective C,Storyboard,Textfield,有没有办法使以下方法成为“全局”方法: 我解释说,我有一个Objective-C项目,上面有ARC和故事板,我的每个视图都有自己的视图控制器类。我的项目中有很多文本字段,有时当用户开始编辑时,键盘会隐藏内容。所以我在网上搜索,想找到解决这个问题的方法。这个主题的答案是:它帮了我很多忙,它可以滚动内容,所以用户总是能够看到视图的底部 但现在我的问题是,我想让这个功能(开始编辑时内容滚动)在我的projet上的任何地方都处于活动状态。未优化的解决方案是在每个视图类中复制代码。但我想知道是否有任何方法

有没有办法使以下方法成为“全局”方法:

我解释说,我有一个Objective-C项目,上面有ARC和故事板,我的每个视图都有自己的视图控制器类。我的项目中有很多文本字段,有时当用户开始编辑时,键盘会隐藏内容。所以我在网上搜索,想找到解决这个问题的方法。这个主题的答案是:它帮了我很多忙,它可以滚动内容,所以用户总是能够看到视图的底部

但现在我的问题是,我想让这个功能(开始编辑时内容滚动)在我的projet上的任何地方都处于活动状态。未优化的解决方案是在每个视图类中复制代码。但我想知道是否有任何方法可以导入包含Those方法或其他内容的类

我的实际代码与这里几乎相同(答案):

我希望在某个地方有一些Objective-C大师可以帮助我解决问题

-编辑-

我在故事板中的每个视图都有自己的UIViewControllerClass。每个带有TextField的字段都有以下代码:

VCExample.h

@interface VCExample : UIViewController

@property (weak, nonatomic) IBOutlet UITextField *oneTextField;

@end
VCExample.m

#import "VCExample.h"
#import "TextFieldScroll.h"

@interface VCExample ()

@end

@implementation VCExample

- (void)viewDidLoad
{
    [super viewDidLoad];

    TextFieldScroll *myTextFieldClass = [[TextFieldScroll alloc] init];
    [self.usernameTextField setDelegate: myTextFieldClass];
    self.usernameTextField.delegate = [TextFieldScroll shared];
}

@end
textfieldcoll.h

#import <Foundation/Foundation.h>

@interface TextFieldScroll : NSObject <UITextFieldDelegate>

+ (id)shared;

@property CGFloat animatedDistance;

@end
#导入
@接口TextFieldScroll:NSObject
+(id)共享;
@属性距离;
@结束
textfieldcoll.m

#import "TextFieldScroll.h"

@implementation TextFieldScroll

@synthesize animatedDistance;

static const CGFloat KEYBOARD_ANIMATION_DURATION = 0.3;
static const CGFloat MINIMUM_SCROLL_FRACTION = 0.2;
static const CGFloat MAXIMUM_SCROLL_FRACTION = 0.8;
static const CGFloat PORTRAIT_KEYBOARD_HEIGHT = 216;
static const CGFloat LANDSCAPE_KEYBOARD_HEIGHT = 162;

+ (id)shared
{
    static TextFieldScroll *sharedMyTextFieldHandler = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^
                  {
                      sharedMyTextFieldHandler = [[self alloc] init];
                  });

    return sharedMyTextFieldHandler;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    CGRect textFieldRect = [self.my.window convertRect:textField.bounds fromView:textField];
    CGRect viewRect = [self.view.window convertRect:self.view.bounds fromView:self.view];

    CGFloat midline = textFieldRect.origin.y + 0.5 * textFieldRect.size.height;
    CGFloat numerator =
    midline - viewRect.origin.y
    - MINIMUM_SCROLL_FRACTION * viewRect.size.height;
    CGFloat denominator =
    (MAXIMUM_SCROLL_FRACTION - MINIMUM_SCROLL_FRACTION)
    * viewRect.size.height;
    CGFloat heightFraction = numerator / denominator;

    if (heightFraction < 0.0)
    {
        heightFraction = 0.0;
    }
    else if (heightFraction > 1.0)
    {
        heightFraction = 1.0;
    }

    UIInterfaceOrientation orientation =
    [[UIApplication sharedApplication] statusBarOrientation];
    if (orientation == UIInterfaceOrientationPortrait ||
        orientation == UIInterfaceOrientationPortraitUpsideDown)
    {
        animatedDistance = floor(PORTRAIT_KEYBOARD_HEIGHT * heightFraction);
    }
    else
    {
        animatedDistance = floor(LANDSCAPE_KEYBOARD_HEIGHT * heightFraction);
    }

    CGRect viewFrame = self.view.frame;
    viewFrame.origin.y -= animatedDistance;

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

    [self.view setFrame:viewFrame];

    [UIView commitAnimations];

}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    CGRect viewFrame = self.view.frame;
    viewFrame.origin.y += animatedDistance;

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];

    [self.view setFrame:viewFrame];

    [UIView commitAnimations];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}
#导入“textfieldcoll.h”
@实现文本字段滚动
@合成动态距离;
静态常量CGFloat键盘\动画\持续时间=0.3;
静态常数CGFloat最小滚动分数=0.2;
静态常数CGFloat最大滚动分数=0.8;
静态常数CGFloat纵向键盘高度=216;
静态常数CGFloat横向键盘高度=162;
+(id)共享
{
静态TextFieldScroll*sharedMyTextFieldHandler=nil;
静态调度一次;
一次发送(一次发送)^
{
SharedBytextFieldHandler=[[self alloc]init];
});
返回sharedMyTextFieldHandler;
}
-(无效)textFieldDidBeginEditing:(UITextField*)textField
{
CGRect textFieldRect=[self.my.window convertRect:textField.bounds fromView:textField];
CGRect viewRect=[self.view.window convertRect:self.view.bounds fromView:self.view];
CGFloat midline=textFieldRect.origin.y+0.5*textFieldRect.size.height;
CGFloat分子=
中线-viewRect.origin.y
-最小滚动分数*viewRect.size.height;
浮点分母=
(最大滚动分数-最小滚动分数)
*viewRect.size.height;
CGFloat heightFraction=分子/分母;
如果(高度分数<0.0)
{
高度分数=0.0;
}
否则如果(高度分数>1.0)
{
高度分数=1.0;
}
界面定向=
[[UIApplication sharedApplication]statusBarOrientation];
如果(方向==UIInterfaceOrientationParative||
方向==UIInterfaceOrientationGraphitalUpsideDown)
{
动画距离=地板(纵向\键盘\高度*高度分数);
}
其他的
{
动画距离=地板(横向键盘高度*高度分数);
}
CGRect viewFrame=self.view.frame;
viewFrame.origin.y-=动画距离;
[UIView beginAnimations:nil上下文:NULL];
[UIView setAnimationBeginsFromCurrentState:是];
[UIView设置动画持续时间:键盘动画持续时间];
[self.view setFrame:viewFrame];
[UIView委员会];
}
-(void)textfielddidediting:(UITextField*)textField
{
CGRect viewFrame=self.view.frame;
viewFrame.origin.y+=动画距离;
[UIView beginAnimations:nil上下文:NULL];
[UIView setAnimationBeginsFromCurrentState:是];
[UIView设置动画持续时间:键盘动画持续时间];
[self.view setFrame:viewFrame];
[UIView委员会];
}
-(BOOL)textField应返回:(UITextField*)textField
{
[textField resignFirstResponder];
返回YES;
}

是的,从技术上讲,您可以使这些方法全球化。我会这样做:

  • 创建响应
    UITextFieldDelegate
    消息的单例NSObject子类

    MyTextFieldHandler.h文件的代码:

    @interface MyTextFieldHandler : NSObject
    
    + (id)shared;
    
    @end
    
    MyTextFieldHandler.m文件的代码:

    + (id)shared
    {
        static MyTextFieldHandler *sharedMyTextFieldHandler = nil;
        static dispatch_once_t onceToken;
    
        dispatch_once(&onceToken, ^
        {
            sharedMyTextFieldHandler = [[self alloc] init];
        });
    
        return sharedMyTextFieldHandler;
    }
    
  • 将所有
    UITextField
    委托设置为此对象

  • 编写在suclass中发送这些消息时需要执行的所有代码

    执行步骤2有更多方法。

  • 可以简单地为所有UITextField对象设置:

    specificTextField.delegate = [MyTextFieldHandler shared];
    anotherSpecificTextField.delegate = [MyTextFieldHandler shared];
    
  • 另一种方法是对UITextField进行子类化,并重写awakeFromNib和initWithFrame:methods,现在将委托设置为:

    self.delegate = [MyTextFieldHandler shared];
    
  • 第三种方法是最难的,但是对于新添加的UITextField,不需要任何额外的代码。您可以使用任何
    UITextField
    方法将委托设置为singleton。阅读马特·汤普森关于方法旋转的帖子:


  • 哪条路最好?取决于您的需要和希望执行的操作。

    最好的方法是为所有视图控制器创建一个基类,该类使用键盘动画代码实现这些方法。将现有视图控制器转换为该基类的子类,并在这些方法的子类实现中将适当的消息发送到
    super

    Hi Legoless,感谢您的快速回答。不幸的是,我尝试了你的建议,但现在没有得到任何结果。我还没有尝试步骤2的选项3。如果查看代码,您将看到对self.view的引用,我应该对代码进行哪些更改,以使self.view引用到textfield的视图。你说的“共享”是什么意思?它不是本机xcode。我也尝试过:textfieldcoll*myDelegate=[[textfieldcoll alloc]init];[self.usernameTextField setDelegate:(id)myDelegate];其中TextFieldScroll是NSO
    self.delegate = [MyTextFieldHandler shared];