Поставяне на бутон като подизглед точно до последния знак на UILable/UITextView

Използвах четири UITextviews, за да поставя всеки параграф. Сега искам да добавя UIButton като подизглед за всеки UITextview.

Осъзнах, че създаването на подизглед с рамка CGRectMake(textview.frame.width-50,textview.frame.height-20,50,20) не е идеалното решение, защото изречението може да завършва навсякъде, имам предвид, че последният знак на всеки абзац може да завършва навсякъде, но позицията му не е постоянна.

И така, най-важното е, че искам да добавя UIButton в рамките на UITextView, точно до думата лат. Как да направя това?

Всяко решение ще бъде високо оценено. :)


person Master Stroke    schedule 16.01.2013    source източник


Отговори (3)


Не е толкова просто. Използвайки:

CGSize sizeOfString = [string sizeWithFont:self.aTextView.font constrainedToSize:self.aTextView.frame.size];

можете да получите CGSize за дадения низ. Но предоставянето на целия низ ще доведе до размер, равен на вашия размер на UITextView (така, долния десен ъгъл)

Трябва да използвате този метод на последния ред на всяко UITextField... и това е трудната част. Пренасянето на думи се извършва от CoreText, UITextView или UILabel не ви дава информация за отделните редове, позиции и т.н.

Трябва да го изчислите сами, правейки нещо подобно (кодът не е толкова чист, ще помогна по-късно, ако имате проблем с разбирането):

NSAttributedString* text = self.aTextView.attributedText;
CTFramesetterRef fs =
CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)text);
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0,0,self.aTextView.frame.size.width - 16,100000));  // why the -16? the frame should be the REAL TEXT FRAME, not the UITextView frame. If you look, there is a space between the view margin and the text. This is the baseline. Probably there is a method to calculate it programatically, but I can't check now. In my case it seems like 8px (*2)
CTFrameRef f = CTFramesetterCreateFrame(fs, CFRangeMake(0, 0), path, NULL);
CTFrameDraw(f, NULL);

NSRange lastRange;
NSArray* lines = (__bridge NSArray*)CTFrameGetLines(f);

id lastLineInArray = [lines lastObject];
CTLineRef theLine = (__bridge CTLineRef)lastLineInArray;
CFRange range = CTLineGetStringRange(theLine);
lastRange.length = range.length;
lastRange.location = range.location - 1;
NSLog(@"%ld %ld", range.location, range.length);

CGPathRelease(path);
CFRelease(f);
CFRelease(fs);

// this is the last line
NSString *lastLine = [self.aTextView.text substringWithRange:lastRange];

Сега можете да използвате:

CGSize sizeOfString = [lastLine sizeWithFont:self.aTextView.font constrainedToSize:self.aTextView.frame.size];

ще получите ширината и височината на низа и след това крайната позиция на вашия бутон (за y позиция: брой редове, взети от броя на редовете в масива * височина на низа)

РЕДАКТИРАНЕ: коментар за лявото пространство в UITextView (причината, поради която има -16 в този ред)

CGPathAddRect(path, NULL, CGRectMake(0,0,self.aTextView.frame.size.width - 16,100000));

Това се случва, защото текстът всъщност не е вътре в UITextView, а в един от неговите подизгледи: UIWebDocumentView (частен клас), който добавя вмъкване. След известно търсене не мога да намеря никакъв метод за получаване (законно) на стойността на тези вмъквания, необходими за предаване на правилния rect на функцията CGPathAddRect(). Можете да направите някои тестове, за да сте сигурни, че винаги е 8pt :-) или да превключите към UILabel, който няма това вмъкване на съдържание

person LombaX    schedule 18.01.2013
comment
Да, нямате нужда от -16, ако използвате UILabel, в този случай няма място за поле ;-) радвам се да чуя, че сте решили проблема си! Приятно кодиране ;-) - person LombaX; 19.01.2013

Трябва да обмислите или използването на UIWebView, или някои приписани на трети страни текстови изгледи, които поддържат такива функции.

UITextView вътрешно използва уеб изглед, което го прави нетривиална работа да разберете точното оформление на текста.

person ZhangChn    schedule 16.01.2013

Мисля, че това е по-добрият начин за използване на tableView. Един параграф в една клетка. Направете клетка без рамка и задайте clearColor на фона на клетките. По този начин можете лесно да добавите бутон.

person Yurec Antidipresant    schedule 18.01.2013