Hoşgeldin. Soru sormak veya cevaplamak için hemen üye ol.
0 oy
1.3k kez görüntülendi
ios development kategorisinde tarafından
Merhabalar, tableview içindeki her hücrede farklı metinler listeliyorum, ve bu liste içersinde .jpg .png uzantılı bir adres varsa asenkron bir şekilde dataya çevirip nstextattechmenta ekleyip daha sonrada ilgili range değerini tanımlayıp resmi uıtextview içine ekliyorum.

Fakat asenkron işlem sırasında, resmin yüklenmesi elemanların oluşturulmasından daha geç olduğundan, il aşamada resim sayfada goruntulenemeiyor. Görünür olan table cell görünmez konuma gelip scrool yapınca tekrar görünür konuma gelirse resim bu sefer görüntülenebiliyor. Bu yuzden bende resim yüklenme işleminin bittiği alanda, reloadRowsAtIndexPaths komutunu kullanıp son görünür olan table cell i yeniliyorum. Fakat bu da tam olarak düzgün çalışmıyor.

Resmin yüklenme işlemi bittikten sonra, istediğim table cell i aynı scool sırasında olduğu gibi yeniden render edilmesini sağlayabileceğim başka bir fonksiyon var mı ?

Yada yukarıdaki table cell içindeki uıtextview içine asenkron resim ekleme sorunumu çözebilecek, herhangi bir fikiriniz var mı ? Ben bir yol bulamadım yardımlarınızı bekliyorum, şimdiden çok teşekkürler.

1 cevap

+1 oy
tarafından
tarafından seçilmiş
 
En İyi Cevap

imajı nasıl çekiyorsunuz? illaki kulandığınız bir httpRequest'i var bu işlem için değilmi?
ilgili imaj request'i başarılı bir şekilde sonuçlandığında UITableView'de beginUpdates, endUpdates'i kullanarak tabloyu yenileyebilirsiniz.

tarafından
imajı normalde haneke swift diye bir kütüphane kullanıp bunla cache leyip çekiyorum.
bunun dışında dispatch_async bloğu içinde de denedim, iamge yüklendiğinde  


cell oluşturulduğu sırada  ilk önce index path değerini cell sınıfının içindeki bir değişkene atıyorum, cell return olmadan once bir fonksiyon içinde image ı yüklüyorum ve image ı attechment içine atıp attrbute text e ekliyorum. eklemenin hemen ardından

beginUpdates
reloadRowsAtIndexPaths [cell içinde atadığım index path değeri]
endUpdates

bu seferde çok resim olan sayfalarda scrool sırasında herşey birbirne giriyor :D ,
bu şekilde kullanmamım lazım hatamı yapıyorum ?

cevabınız için çok teşekkürler.

işlemini gerçekleştiriyorum, bu seferde
tarafından
hatta hızlı soocroll yaptığımda hücreler bir birin üstüne gelip ardından 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 2 beyond bounds [0 .. 1]

hatası alıyorum, bayada uğraştım ama çözemedim :(
tarafından
tam olarak karşılaştığınız problem nedir anlayamadım ama muhtemelen tableView'in reusable cell yapısı nedeniyle bir şeyler yanlış gidiyor ve cell içerikleri bir birlerine karışıyor anlaşılan. :)

problem yaşadığınız kod'a ait basitleştirilmiş bir örneği burada paylaşabilirseniz, daha hızlı bir şekilde yardımcı olmaya çalışayım.
tarafından
tarafından düzenlendi
Tab ki,

Sizinde vaktinizi alıyorum kusruma bakmayın,

Burası tableview in hücrelerinin oluşturulduğu block

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let entry = self.entryList[indexPath.row]
        
        if let yazar_id = entry.valueForKeyPath("yazar_id") as? String,var metin = entry.valueForKeyPath("metin") as? String{
            let cell = tableView.dequeueReusableCellWithIdentifier("baslikEntryListTVCell", forIndexPath: indexPath) as! baslikEntryListTVCell
            cell.cellIndexPath.append(indexPath)
            self._currentIndexPath = indexPath
            cell.attrText = NSMutableAttributedString(string: metin.regexReplace("<br />", replace: "\n"))
            cell.entryMetinTextV.attributedText = cell.attrText
            cell.derle(entry)
            cell.kuladiWidthConst.constant = view.frame.width - 190
            yazar_id
            return cellOptimize(cell,yazar_id: yazar_id,metin: metin)
            
                
        }else{
            return tableView.dequeueReusableCellWithIdentifier("baslikEntryListTVCell", forIndexPath: indexPath) as! baslikEntryListTVCell
        }
        
    }
    
    func cellOptimize(cell:baslikEntryListTVCell,yazar_id:String,var metin:String)->baslikEntryListTVCell{
        Alamofire.request(.GET, consts._apiUrl, parameters: ["a":consts._apiKey,"n":"ben","uye_id":yazar_id])
            .responseJSON { response in
                if let JSON = response.result.value {
                    if let uyebilgileri = JSON["uyebilgileri"] as? NSObject{
                        if let uye_resim_url = uyebilgileri.valueForKey("resmum"){
                            cell.userImage.hnk_setImageFromURL(NSURL(string: uye_resim_url as! String)!)
                        }
                        
                    }
                }
        }
       
        cell.matchsGorsel = metin.regexMatch("(?<=\\(img:)(.*?)(?=\\))");


        
            for match in cell.matchsGorsel{
                if let src = match.valueForKey("src"),let location = match.valueForKey("location"){
                    if src.hasPrefix("#"){
                        let gorsel_id = (src as! String).regexReplace("#", replace: "")
                        let URLJ = NSURL(string: "http://www.site.com/api/?a=huseyinul528754&n=galeri&w=gorsel_id&gorsel_id=\(gorsel_id)")!
                        cacheJ.fetch(URL: URLJ).onSuccess { JSON in
                            if let src = JSON.dictionary?["url_m"]{
                                self.entryTextViewURLtoIMGss(cell, location: (location as! Int), src: (src as! String), textView: cell.entryMetinTextV,leng: gorsel_id.characters.count)
                                
                            }
                        }
                    }
                    
                }
        }
    }




    func entryTextViewURLtoIMGs(cell:baslikEntryListTVCell,location:Int,var src:String,textView:UITextView,leng:Int=0){
        var lng = src.characters.count
        if(leng>0){ lng=leng}
        src = src.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
        
        let URL = NSURL(string: src)!
        let fetcher = NetworkFetcher<NSData>(URL: URL)
        
        //let  i = String(cell.cellIndexPath[0].row)
        print(derlenen)
        cache.fetch(fetcher: fetcher).onSuccess { data in
            let attributedString = cell.attrText
            let textAttachment = NSTextAttachment()
            
            if let image = UIImage(data: data){
                textAttachment.image = image
                cell.entryMetinTextV.attributedText = attributedString
                
               // if cell.entryMetinTextV.text
                let oldWidth = textAttachment.image!.size.width;
                print(oldWidth)
                //I'm subtracting 10px to make the image display nicely, accounting
                //for the padding inside the textView
                var scaleFactor = oldWidth / (textView.frame.width - 10)
                
                if(image.size.width<textView.frame.width-100){
                    scaleFactor = oldWidth / oldWidth
                }
                
                scaleFactor = oldWidth / (textView.frame.width - 10)
                
                //print("slace : \(scaleFactor) image size : \(image.size.width) org : \(image.size.width)")
                
                
                textAttachment.image = UIImage(CGImage: textAttachment.image!.CGImage!, scale: scaleFactor, orientation: .Up)
                
                let attrStringWithImage = NSAttributedString(attachment: textAttachment)
                
                
                attributedString.replaceCharactersInRange(NSMakeRange(location,1), withAttributedString: attrStringWithImage)
                
                
                let mysRange = NSRange(location:0, length:5) // range of "Swift"
                let mysCustomAttribute = ["click":"src:\(src),type:image"]
                attributedString.addAttributes(mysCustomAttribute, range: mysRange)
                print(attributedString.length)
                attributedString.addAttribute(NSFontAttributeName,value: UIFont(name: "AmericanTypewriter-Bold",size:9)!,range: NSRange(location:0,length:5))
                
                cell.entryMetinTextV.attributedText = attributedString
                
                
                
                if let _ = self._currentIndexPath {
                    self.baslikEntryListTV.beginUpdates()
                    //self.baslikEntryListTV.reloadRowsAtIndexPaths(cell.cellIndexPath, withRowAnimation: UITableViewRowAnimation.None)
                    self.derlenen[cell.cellIndexPath[0].row] = 1
                    self.baslikEntryListTV.endUpdates()
                    print(self.derlenen)
                    print(" burada  \(cell.cellIndexPath[0].row)")
                }
                else {
                    // `_currentIndexPath` is nil.
                    // Error handling if needed.
                }
                
                
            }
            
        }
        
    }



Dosyalar birbirine entegre ve buyuk olduğu için yollayamadım, app i gondermem gerkiyorsa, sorunun olduğu alanın ufak bir örneğini hazırlayıp yollayabilrim.

Şuanda scrool yaptığımda diğer hucreler yüklenip ardından resim yükleme tamamladığında yenilendiğinden, bu art arda oluyor ve sayfada celler üst üste gelip, NSRangeException hatasını aliyorum.
tarafından
hmm, tam tahmin ettiğim gibi. :)
tableView'in reusable cell yapısının nasıl kullanılacağını iyi anlamalısınız. verdiğiniz örnek'de baya bir karıştırmışsınız işi. :)


tableView ve custom tableViewCell'in nasıl çalıştığını anlatan örnek bir kod hazırladım.
boş bir proje oluşturup, projede custom biew UIView class'ı oluşturun ve aşağıda verdiğim kodu bu class'ın içerisine kopyalayın.
daha sonra bu custom class''ı viewController içerisine bir subView olarak ekleyin ve çalıştırın.

oluşturulan tableView ve içeiriğinin hangi sırayla oluşturulduğunu ve reusable yapısının tableView scroll edildiğinde nasıl çalıştığını xcode log alanında çıkan logları takip ederek çok daha iyi kavrayabilirsiniz.





import UIKit

class myCustomTableViewCell:UITableViewCell {
    
    var cellIndexTextView:UITextView! =  nil
    var customTextView:UITextView! = nil
    var roundedTextView:UITextView! = nil
    
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        
        
        self.customTextView = UITextView(frame: self.frame)
        self.customTextView.backgroundColor = UIColor.redColor()
        self.customTextView.textAlignment = NSTextAlignment.Center
        self.contentView.addSubview(self.customTextView)

        
        self.cellIndexTextView = UITextView(frame: CGRectMake(0, 0.0, self.contentView.frame.size.height, self.contentView.frame.size.height))
        self.cellIndexTextView.backgroundColor = UIColor.whiteColor()
        self.cellIndexTextView.textAlignment = NSTextAlignment.Center
        self.contentView.addSubview(self.cellIndexTextView)
        
        self.roundedTextView = UITextView(frame: CGRectMake(self.contentView.frame.size.width - self.contentView.frame.size.height, 0.0, self.contentView.frame.size.height, self.contentView.frame.size.height))
        self.roundedTextView.backgroundColor = UIColor.lightGrayColor()
        self.roundedTextView.textAlignment = NSTextAlignment.Center
        self.contentView.addSubview(self.roundedTextView)

        
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}





class tableViewWithCustomCell: UIView, UITableViewDelegate, UITableViewDataSource {

    var myTableView:UITableView! = nil
    var myTempDataArray:[Dictionary<String,AnyObject>] = [
        ["name":"ahmet","age":12],
        ["name":"mehmet","age":23],
        ["name":"mustafa","age":34],
        ["name":"ali","age":56],
        ["name":"ömer","age":23],
        ["name":"salih","age":54],
        ["name":"ziya","age":65],
        ["name":"veli","age":32],
        ["name":"selçuk","age":26],
        ["name":"uğur","age":66],
        ["name":"koray","age":16],
        ["name":"faruk","age":75],
        ["name":"ahmet","age":12],
        ["name":"mehmet","age":23],
        ["name":"mustafa","age":34],
        ["name":"ali","age":56],
        ["name":"ömer","age":23],
        ["name":"salih","age":54],
        ["name":"ziya","age":65],
        ["name":"veli","age":32],
        ["name":"selçuk","age":26],
        ["name":"uğur","age":66],
        ["name":"koray","age":16],
        ["name":"faruk","age":75]
    ]
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        self.myTableView = UITableView(frame: self.frame)
        self.myTableView.delegate = self
        self.myTableView.dataSource = self
        self.addSubview(self.myTableView)
 
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.myTempDataArray.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var Identifier:String = "myCell"
        var myCell:myCustomTableViewCell! = nil
        if var cell:myCustomTableViewCell = tableView.dequeueReusableCellWithIdentifier(Identifier) as? myCustomTableViewCell {
            println("\(indexPath.row) numaralı cell daha önce oluşturulmuş. o zaman çağıralım.")
            myCell = cell
        } else {
            //custom tableView cell'ini bir kere oluşturuyor ve "myCell" adında bir identifier veriyoruz.
            println("\(indexPath.row) numaralı cell'i oluşturalım")
            myCell = myCustomTableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: Identifier)
        }
        
        
        //data array'ımızın içerisindeki verileri parse edelim ve boş değişkenlere atayalım
        let myData:Dictionary<String,AnyObject> = self.myTempDataArray[indexPath.row]
        var name:String = ""
        var age:Int = 0
        if let rawName:String = myData["name"] as? String {
            name = rawName
        }
        if let rawAge:Int = myData["age"] as? Int {
            age = rawAge
        }
        
        myCell.cellIndexTextView.text = String(format: "sıra\n%i", indexPath.row)
        myCell.customTextView.text = name
        myCell.roundedTextView.text = String(format: "yaş\n%i", age)
        return myCell
    }
    
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
tarafından
sizi aptalca gelicek ama :D , açılan view controler içine

    override func viewWillAppear(animated: Bool) {
        var customView:simpleView = simpleView()
        customView.frame = view.frame
        view.addSubview(customView)
    }

UIView clası içine paylaştığınız  kodları yapıştırdığım custom clasımı dahil etim fakat hiçbirşey görüntülüyemedim.  bunun dışında birşey yapıcak mıydım. yukarıdaki clasları dahil etiğim uiview classı içinde çağırmak gibi

teşekkrüler.
tarafından
Oluşturduğunuz simpleview class'ının init metodu içerisinde frame'i set etmelisiniz.
SimpleView(frame:view.frame) şeklinde yani.
Verdiğim örnekte dikkat ederseniz tableView init metodu içerisinde yaratılıyor.
Init ettikten sonra view frame'i tanımlamaya çalışmak beyhude. :)
tarafından
tarafından düzenlendi
selamlar cevabınız için çok teşekkür ederim, haklısınız çalışma mantığı ile ilgili eksik bilgilerim var örneğinizi inceledim fakat sorunumu bundan devam ederek çözemedim.

basit bir listeleme örneği hazırladım, bu örnekte table cell içindeki textview in scrool durumu enabled bu sayede resimler sorunsuz yüklenebiliyor. Fakat düzgün bir götüntü oluşması için scrool disabled olması lazım işte sorun tamda burda başlıyor ve resimleri goruntüleyemiyorum.

Bunun dışında aklama takılan bir kaç noktayı kodların arasında yorum olarak yazdım, eğer ilgilenebilirseniz beni buyuk bir derten kurtarız ve duamı alırsınız.

ilginiz için çok teşekkür ederim.

Örnek uygulama linki aşağıdadır.

https://drive.google.com/folderview?id=0B4MEF11v_cH3d053YmVJZGE2d2c&usp=sharing

zip linki
https://drive.google.com/open?id=0B4MEF11v_cH3OHZyOGtnX3JIWmM
tarafından
proje dosyanızı zipleyip google drive'a yüklerseniz daha iyi olur sanırım, bu haliyle teker teker klasör ve içerikleri indirmek gerekiyor.
tarafından
tabi hemen ekliyorum farketmemişim,
tarafından
tarafından düzenlendi
drive sağ tıklayıp indir dediğimde tüm dosyayıda indirebildim, ama sizin için zip dosyasınıda ekledim.
zip linki  şu ;
https://drive.google.com/open?id=0B4MEF11v_cH3OHZyOGtnX3JIWmM

davamı bu konuda =>
http://forum.yasinturkoglu.com/820/uitextview-i%C3%A7inde-resim-g%C3%B6r%C3%BCnt%C3%BCleme-s%C4%B1ras%C4%B1nda-height-sorunu
...