iOS字典中的画词查词功能

日常学习小语种时,在使用字典的时候我们更多的是去研究一个词,熟悉它的语法,了解它的使用场景,那么在移动设备上也同样是一个道理,我们如何通过自己的手势操作在屏幕中找到我想要的单词来学习它呢。在这里我是这样考虑的,首先能拿到这个单词是主要任务,其次是怎么样才知道这个单词就是我想要的。所以我要在单词上加一个选中的状态,然后通过放大镜来展现给使用者。非常自然。

好,我们正式开始!

$ 我们定义一个UILabel的类,来处理label上的text;

$ 定义一个单词类(DZWord),来接收label上的单词和单词的frame;

$ 之后就是要拿到这个单词和为这个单词加一个选中状态;

$ 画词功能实现后,最后我们实现就是要查找这个单词;

UILabel+DZLabel.h 为UILabel定义一个+方法

  • (NSArray )currentlabel:(UILabel )label; 处理label.text,返回数组,元素对象为单词类;
+ (NSArray *)currentlabel:(UILabel *)label
{
NSMutableArray * array = [NSMutableArray array];
NSString * string = label.text;
if (string == nil) {
    return nil;
}
char str[string.length];
strcpy(str, [string UTF8String]);
CGPoint point = CGPointMake(0, 0);
//定义一个指针指向字符串的首地址
char * fun = str;//char * fun = &str[0]
int temp = 0;
for (; (*fun) != '\0'; fun++) {
    char * word = malloc(sizeof(char));
    int i = 0;
    while ((isalpha(*fun) || (*fun) == '\'') && (*fun) != '\0') {
        word[i++] = *fun;
        fun++;
        temp = 1;
    }
    if (1 == temp) { 
        word[i] = '\0';   
        DZWord * dzword = [[DZWord alloc]init];
        dzword.wording = [NSString stringWithUTF8String:word];
        //计算出单词的 width height
        CGSize  wordSize = [dzword.wording sizeWithAttributes:@{NSFontAttributeName:label.font}];
        //计算最后一个单词是否换到下一行
        NSString * single = [NSString stringWithFormat:@"%c",*(fun)]; 
        CGSize singleSize = [single sizeWithAttributes:@{NSFontAttributeName:label.font}];
        if([single isEqualToString:@" "])
        {
            singleSize.width = 0;
        }
        //换行
        if (point.x + singleSize.width + wordSize.width > label.bounds.size.width) {
            point.x = 0;  
            point.y += wordSize.height;
        }
        //第一个单词的frame
        dzword.frame = CGRectMake(point.x, point.y, wordSize.width, wordSize.height); 
        //通过单词的宽累加,来确定单词的距屏幕左端的距离
        point.x += wordSize.width;
        [array addObject:dzword];     
    }
    temp = 0;
    if (*fun == '(') {
        break;
    }
    NSString * single = [NSString stringWithFormat:@"%c",*(fun)];
    CGSize singleSize = [single sizeWithAttributes:@{NSFontAttributeName:label.font}];
    //无关字符宽累加 空格 确定下一个单词的point.x
    point.x += singleSize.width;

    }
return  [array copy];
}

定义一个单词类(DZWord)来接收单词和单词的frame,首先引入#import<CoreGraphics/CoreGraphics.h>

@property (nonatomic,copy) NSString * wording;

@property (nonatomic) CGRect frame;    

以上所讲述的什么执行呢???我们为tableView添加一个手势;

UILongPressGestureRecognizer * longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];

longPress.minimumPressDuration = 0.5;

[self.tableView addGestureRecognizer:longPress];

通过当前的手势来确定放大镜的位置和点击的cell;

- (void)longPressAction:(UILongPressGestureRecognizer *)sender
{
switch (sender.state) {
    case UIGestureRecognizerStateBegan:
    {
        //当前手指触摸屏幕的位置
        CGPoint point = [sender locationInView:self.tableView];
        //放大镜的位置
        [self magnifierPosition:point];
        //显示放大镜
        [self.magnifierView makeKeyAndVisible];
        //通过这个点来确定当期点击的cell
        [self cellOnWord:point];
        break;
    }
    case UIGestureRecognizerStateChanged:
    {
        CGPoint point = [sender locationInView:self.tableView];
        [self magnifierPosition:point];
        [self cellOnWord:point];
        break; 
    }
    case UIGestureRecognizerStateEnded:
    {
        CGPoint point = [sender locationInView:self.tableView];
        [self.magnifierView setHidden:YES];
        [self cellOnWord:point];
        if (self.wordView.isHidden == NO) {
               NSLog(@"%@",self.currentString);
            [self systemDictionarie:self.currentString];
        }
        break;
    }
    default:
        break;
}
}

根据当前点击的cell来确定单词的frame,并为单词加一个选中状态;

- (void)cellOnWord:(CGPoint)point
{
NSIndexPath * indexpath = [self.tableView indexPathForRowAtPoint:point];
PhraseCell * cell = [self.tableView cellForRowAtIndexPath:indexpath];
NSArray * array = [UILabel currentlabel:cell.phraseLabel];
for (DZWord * word in array) {
    CGRect frame = word.frame;
    frame.origin.x += cell.frame.origin.x + 20;
    frame.origin.y += cell.frame.origin.y + 20;
    if ([self pointInRectangle:frame point:point]) {

        self.wordView.hidden = NO;
        self.wordView.frame = frame;
        self.wordView.backgroundColor = [UIColor colorWithRed:.5 green:0.5 blue:.3 alpha:.5];
        [self.tableView addSubview:self.wordView];

        self.currentString = word.wording;
        return;
    }
}
self.wordView.hidden = YES;
}

判断你当前点击的点是否在单词frame的矩内,来判断是否为单词加一个选中状态;

- (BOOL) pointInRectangle:(CGRect )rech point:(CGPoint)clickPoint
{
if (clickPoint.x > rech.origin.x && clickPoint.x < (rech.origin.x + rech.size.width) && clickPoint.y > rech.origin.y  &&  clickPoint.y < (rech.origin.y + rech.size.height)) {
    return YES;
}
return NO;
}

放大镜的位置,针对于放大镜的一些设置都可以在CHMagnifierView进行设置;

-(void)magnifierPosition:(CGPoint)point
{
//设置放大镜的位置
CGPoint magnifierPoint = point;
int y = magnifierPoint.y - self.tableView.contentOffset.y - 30;
magnifierPoint.y = y;
self.magnifierView.pointToMagnify = magnifierPoint;
}

单独写一下与上面方法 CHMagnifierView 这个类;

- (void)setPointToMagnify:(CGPoint)pointToMagnify
{
_pointToMagnify = pointToMagnify;     
CGPoint center = CGPointMake(pointToMagnify.x, self.center.y);
if (pointToMagnify.y > CGRectGetHeight(self.bounds) * 0.5) {
    center.y = pointToMagnify.y -  CGRectGetHeight(self.bounds) / 2;
}
self.center = center;
[self.contentLayer setNeedsDisplay];
}    

OK,你现在已经能拿到一个单词,并为它加一个标志,尽情松开手指,让我们看看到底是什么语法是我们所不知道的!

- (void)systemDictionarie:(NSString *)word
{
UIView *view = [[UIView alloc] initWithFrame:self.view.bounds];
view.backgroundColor = [UIColor grayColor];
view.alpha = .5;
[self.view.window addSubview:view];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    // 子线程 
    NSLog(@"%@",word);
    UIReferenceLibraryViewController *referenceLibraryViewController =[[UIReferenceLibraryViewController alloc] initWithTerm:word];  
    // 主线程
    dispatch_async(dispatch_get_main_queue(), ^{
        [view removeFromSuperview];     
        [self presentViewController:referenceLibraryViewController
                           animated:YES
                         completion:nil];
        self.wordView.hidden = YES;
    });
});
}

完成上述功能,基本上已经实现移动设备上画词查词的功能了,昂,忘了,我比较懒!哈

- (CHMagnifierView *)magnifierView
{
if (!_magnifierView) {
    _magnifierView = [[CHMagnifierView alloc] init];
    _magnifierView.viewToMagnify = self.tableView.window;
}
return _magnifierView;
}

- (UIView *)wordView
{
if (!_wordView) {
    _wordView = [[UIView alloc] init];
}
return _wordView;
}