SORU
21 AĞUSTOS 2013, ÇARŞAMBA


İOS 7 UİTextView yüksekliği ile UİTableViewCell?

Nasıl iOS 7'de bir UİTextView ile bir UİTableViewCell yüksekliğini hesaplamak miyim?

Benzer sorular çok fazla cevap buldum ama sizeWithFont: her çözüm içinde yer alır ve bu yöntem önerilmiyor!

- (CGFloat)tableView:heightForRowAtIndexPath: ama nasıl benim TextView tüm metin görüntülemek için ihtiyacı olan yüksekliği hesaplanır? kullanmak zorunda olduğumu biliyorum

CEVAP
15 EYLÜL 2013, Pazar


Her şeyden önce, metin nasıl oluşturulur gelince UİTextView ve UİLabel arasında büyük bir fark olduğu çok önemli not. Sadece UİTextView tüm sınırları parçalar, ama aynı zamanda biraz farklıdır içinde metin düzeni var.

Bu nedenle, sizeWithFont: UİTextViews için gitmek için kötü bir yoldur.

Bunun yerine UITextView kendisi küçük boyutu sınırlayıcı kutu içinde UITextView tüm içeriğini görüntülemek için gerekli dönecektir, belirttiğiniz işlevi sizeThatFits: çağırdı.

Aşağıdaki eşit ve eski sürümleri iOS 7 de çalışır ve şu an itibariyle kaldırılmış olan herhangi bir yöntem içermez.


Basit Çözüm

- (CGFloat)textViewHeightForAttributedText: (NSAttributedString*)text andWidth: (CGFloat)width {
    UITextView *calculationView = [[UITextView alloc] init];
    [calculationView setAttributedText:text];
    CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];
    return size.height;
}

Bu işlev NSAttributedString CGFloat istenilen genişlik ve yükseklik almak gerekli dönecektir


Detaylı Çözüm

Geçenlerde benzer bir şey yaptım ben de karşılaştım bağlı Sorunlar için bazı çözümler paylaşmak istedim. Biri yardımcı olacağını umuyoruz.

Bu çok daha derin olduğunu ve şu: kapsayacaktır

  • Tabii ki: UITableViewCell boyutu tam içeriğini görüntülemek için gerekli temel yüksekliği ayarı UITextView . içerdiği
  • Metin değişiklikleri için (satır-yükseklik değişiklikleri animasyon) cevap
  • Görünür alanı içinde imleci tutmak ve ilk tutma düzenlerken UITableViewCell yeniden boyutlandırma UITextView üzerinde yanıtlayıcı

Statik bir tablo görünümü ile çalışmak ya da sadece UITextViews bilinen bir dizi varsa, potansiyel olarak adım 2 çok daha basit hale getirebilirsiniz.

1. İlk olarak, heightForRowAtİndexPath üzerine:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    // check here, if it is one of the cells, that needs to be resized
    // to the size of the contained UITextView
    if (  )             
        return [self textViewHeightForRowAtIndexPath:indexPath];
    else
    // return your normal height here:
            return 100.0;           
}

2. Gerekli yüksekliği hesaplanır: bu işlev tanımlayın

Örneği UITableViewController alt değişken olarak NSMutableDictionary (Bu örnekte textViews denir) ekleyin.

Bu sözlük bu kadar: bireysel UITextViews başvurular depolamak için kullanın

(ve evet, indexPaths are valid keys for dictionaries)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Do you cell configuring ...

    [textViews setObject:cell.textView forKey:indexPath];
    [cell.textView setDelegate: self]; // Needed for step 3

    return cell;
}

Bu işlev artık gerçek yüksekliğini hesaplamak

- (CGFloat)textViewHeightForRowAtIndexPath: (NSIndexPath*)indexPath {
    UITextView *calculationView = [textViews objectForKey: indexPath];
    CGFloat textViewWidth = calculationView.frame.size.width;
    if (!calculationView.attributedText) {
        // This will be needed on load, when the text view is not inited yet

        calculationView = [[UITextView alloc] init];
        calculationView.attributedText = // get the text from your datasource add attributes and insert here
        textViewWidth = 290.0; // Insert the width of your UITextViews or include calculations to set it accordingly
    }
    CGSize size = [calculationView sizeThatFits:CGSizeMake(textViewWidth, FLT_MAX)];
    return size.height;
}

3. Düzenleme Yeniden Boyutlandırma sağlar

Önümüzdeki iki fonksiyonları için UITextViews temsilci senin için UITableViewController ayarlanır önemlidir. Eğer temsilci olarak başka bir şeye ihtiyacın olursa, oradan ilgili aramaları veya uygun NSNotificationCenter kanca kullanarak çözüm bulabilirsiniz.

- (void)textViewDidChange:(UITextView *)textView {

    [self.tableView beginUpdates]; // This will cause an animated update of
    [self.tableView endUpdates];   // the height of your UITableViewCell

    // If the UITextView is not automatically resized (e.g. through autolayout 
    // constraints), resize it here

    [self scrollToCursorForTextView:textView]; // OPTIONAL: Follow cursor
}

4. Düzenleme yaparken imleci takip edin

- (void)textViewDidBeginEditing:(UITextView *)textView {
    [self scrollToCursorForTextView:textView];
}

Bu ise UİTableView görünen Dörtgen içinde değilse imleç konumuna UITableView kaydırma yapın

- (void)scrollToCursorForTextView: (UITextView*)textView {

    CGRect cursorRect = [textView caretRectForPosition:textView.selectedTextRange.start];

    cursorRect = [self.tableView convertRect:cursorRect fromView:textView];

    if (![self rectVisible:cursorRect]) {
        cursorRect.size.height  = 8; // To add some space underneath the cursor
        [self.tableView scrollRectToVisible:cursorRect animated:YES];
    }
}

5. Görünür rect, ayar parçalar ile ayarlayın

Düzenlerken, UITableView parçalar Klavye ile kaplı olabilir. Eğer parçalar, scrollToCursorForTextView: ayarsızdır bu tableviews imleci kaydırmak için mümkün olacak değil, eğer tableview alt kısmında ise.

- (void)keyboardWillShow:(NSNotification*)aNotification {
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(self.tableView.contentInset.top, 0.0, kbSize.height, 0.0);
    self.tableView.contentInset = contentInsets;
    self.tableView.scrollIndicatorInsets = contentInsets;
}

- (void)keyboardWillHide:(NSNotification*)aNotification {
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.35];
    UIEdgeInsets contentInsets = UIEdgeInsetsMake(self.tableView.contentInset.top, 0.0, 0.0, 0.0);
    self.tableView.contentInset = contentInsets;
    self.tableView.scrollIndicatorInsets = contentInsets;
    [UIView commitAnimations];
}

Ve son kısmı:

Görünümü doldurdun içinde NSNotificationCenter Klavye değişikliklerin Bildirimleri için kaydolun:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

Lütfen bu cevap o kadar uzun yapmak için bana kızıyor yok. Hepsini değil soruyu cevaplamak için gerekli süre, doğrudan ilgili bu konularda yardımcı olacak kişi olduğuna inanıyorum.


GÜNCELLEME:

Dave Haupert belirttiği gibi, rectVisible fonksiyon eklemeyi unutmuşum:

- (BOOL)rectVisible: (CGRect)rect {
    CGRect visibleRect;
    visibleRect.origin = self.tableView.contentOffset;
    visibleRect.origin.y  = self.tableView.contentInset.top;
    visibleRect.size = self.tableView.bounds.size;
    visibleRect.size.height -= self.tableView.contentInset.top   self.tableView.contentInset.bottom;

    return CGRectContainsRect(visibleRect, rect);
}

Ayrıca scrollToCursorForTextView: hala bana bir projeden TextField öğeleri biri için doğrudan bir referans dahil olduğunu fark ettim. Eğer bodyTextView ile ilgili bir sorun tespit edildikten varsa, işlevi güncelleştirilmiş sürümünü kontrol edin.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Charles Nesson

    Charles Ness

    27 NİSAN 2006
  • wwjoshdu

    wwjoshdu

    18 ŞUBAT 2011
  • JeezyVEVO

    JeezyVEVO

    12 Mayıs 2009