2012-05-28 13 views
20

का कारण बनता है मैं आपको अपनी समस्या के बारे में बताता हूं और मैंने इसे हल करने का प्रयास कैसे किया। मेरे पास एक UIScrollView है जो उप-दृश्यों को बाएं से दाएं स्क्रॉल के रूप में लोड करता है। प्रत्येक सबव्यू में 400x200 के आसपास 10-20 छवियां होती हैं। जब मैं देखने के लिए दृश्य से स्क्रॉल करता हूं, तो मुझे काफी अंतराल का अनुभव होता है।UIImageView की छवि प्रॉपर्टी सेट करना प्रमुख अंतराल

जांच के बाद, मैंने पाया कि सभी विचारों को उतारने और फिर से प्रयास करने के बाद, अंतराल समाप्त हो गया था। मुझे लगा कि छवियों का सिंक्रोनस कैशिंग अंतराल का कारण था। इसलिए मैंने UIImageView का उप-वर्ग बनाया जिसने छवियों को असीमित रूप से लोड किया। लोडिंग कोड निम्न जैसा दिखता है (self.dispatchQueue एक धारावाहिक प्रेषण कतार देता है)।

- (void)loadImageNamed:(NSString *)name { 
    dispatch_async(self.dispatchQueue, ^{ 
     UIImage *image = [UIImage imageNamed:name]; 

     dispatch_sync(dispatch_get_main_queue(), ^{ 
      self.image = image; 
     }); 
    }); 
} 

हालांकि, इस उपवर्ग के लिए मेरे UIImageViews के सभी परिवर्तित करने के बाद, मैं अभी भी अंतराल अनुभव (मुझे यकीन है कि अगर यह कम या नहीं किया गया था नहीं कर रहा हूँ)। मैंने समस्या का कारण self.image = image; पर उबाला। यह इतना अंतराल क्यों है (लेकिन केवल पहले लोड पर)?

कृपया मेरी मदद करें। = (

उत्तर

51

पी एस एसडीके 4.2 iOS5 iphone पर परीक्षण किया संपादित करें 2:।। यहाँ एक स्विफ्ट संस्करण है कि कुछ सुधार शामिल हैं। (अनचाहे।) https://gist.github.com/fumoboy007/d869e66ad0466a9c246d


संपादित करें: असल में, मेरा मानना ​​है कि आवश्यक सभी आवश्यक है। (Untested है।)

- (void)loadImageNamed:(NSString *)name { 
    dispatch_async(self.dispatchQueue, ^{ 
     // Determine path to image depending on scale of device's screen, 
     // fallback to 1x if 2x is not available 
     NSString *pathTo1xImage = [[NSBundle mainBundle] pathForResource:name ofType:@"png"]; 
     NSString *pathTo2xImage = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"png"]; 

     NSString *pathToImage = ([UIScreen mainScreen].scale == 1 || !pathTo2xImage) ? pathTo1xImage : pathTo2xImage; 


     UIImage *image = [[UIImage alloc] initWithContentsOfFile:pathToImage]; 

     // Decompress image 
     if (image) { 
      UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale); 

      [image drawAtPoint:CGPointZero]; 

      image = UIGraphicsGetImageFromCurrentImageContext(); 

      UIGraphicsEndImageContext(); 
     } 


     // Configure the UI with pre-decompressed UIImage 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      self.image = image; 
     }); 
    }); 
} 

मूल जवाब: ऐसा लगता है कि यह self.image = image; सीधे नहीं था। UIImage छवि लोडिंग विधियां तुरंत छवि डेटा को डीकंप्रेस और संसाधित नहीं करती हैं; जब वे दृश्य अपने प्रदर्शन को रीफ्रेश करते हैं तो वे ऐसा करते हैं। तो समाधान कोर ग्राफिक्स के स्तर को कम करने और छवि डेटा को डीकंप्रेस और संसाधित करना था। नया कोड निम्न जैसा दिखता है।

- (void)loadImageNamed:(NSString *)name { 
    dispatch_async(self.dispatchQueue, ^{ 
     // Determine path to image depending on scale of device's screen, 
     // fallback to 1x if 2x is not available 
     NSString *pathTo1xImage = [[NSBundle mainBundle] pathForResource:name ofType:@"png"]; 
     NSString *pathTo2xImage = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"png"]; 

     NSString *pathToImage = ([UIScreen mainScreen].scale == 1 || !pathTo2xImage) ? pathTo1xImage : pathTo2xImage; 


     UIImage *uiImage = nil; 

     if (pathToImage) { 
      // Load the image 
      CGDataProviderRef imageDataProvider = CGDataProviderCreateWithFilename([pathToImage fileSystemRepresentation]); 
      CGImageRef image = CGImageCreateWithPNGDataProvider(imageDataProvider, NULL, NO, kCGRenderingIntentDefault); 


      // Create a bitmap context from the image's specifications 
      // (Note: We need to specify kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little 
      // because PNGs are optimized by Xcode this way.) 
      CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
      CGContextRef bitmapContext = CGBitmapContextCreate(NULL, CGImageGetWidth(image), CGImageGetHeight(image), CGImageGetBitsPerComponent(image), CGImageGetWidth(image) * 4, colorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little); 


      // Draw the image into the bitmap context 
      CGContextDrawImage(bitmapContext, CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)), image); 

      // Extract the decompressed image 
      CGImageRef decompressedImage = CGBitmapContextCreateImage(bitmapContext); 


      // Create a UIImage 
      uiImage = [[UIImage alloc] initWithCGImage:decompressedImage]; 


      // Release everything 
      CGImageRelease(decompressedImage); 
      CGContextRelease(bitmapContext); 
      CGColorSpaceRelease(colorSpace); 
      CGImageRelease(image); 
      CGDataProviderRelease(imageDataProvider); 
     } 


     // Configure the UI with pre-decompressed UIImage 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      self.image = uiImage; 
     }); 
    }); 
} 
+0

ओह ... उस छोटी सी बग के बारे में खेद है। – fumoboy007

+0

यह बहुत उपयोगी था। इस प्रश्न पर आने वाले लोगों के लिए सिर्फ UIView से UIImage बनाने की आवश्यकता है, मुझे कई उत्तरों के माध्यम से पाई जाने के बाद यह समाधान मिला: 'UIGraphicsBeginImageContext (processing.bounds.size); 'CGContextRef ctx = UIGraphicsGetCurrentContext(); '[processing.layer renderInContext: ctx]; 'UIImage * finalImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); ' –

+0

धन्यवाद! .... –

1

मुझे लगता है कि समस्या स्वयं छवियां हो सकती है। उदाहरण के लिए - मुझे अपनी परियोजनाओं में से एक में मिला है 10 छवियों 640x600 एक दूसरे पर अल्फा पारदर्शिता के साथ स्तरित। जब मैं इस व्यू कंट्रोलर से पुश या पॉप व्यू कंट्रोलर को पॉप करने का प्रयास करता हूं .. यह एक बहुत lags

जब मैं केवल कुछ चित्र छोड़ सकते हैं या का उपयोग काफी छोटे आकार के चित्रों - कोई अंतराल 4.

+1

लेकिन मेरा केवल पहले लोड पर लगी है! – fumoboy007

संबंधित मुद्दे