जवाबों:
सबसे अच्छी विधि जो मैंने कभी भी UIScrollView
अपने समाहित साक्षात्कारों के आधार पर सामग्री के आकार को अद्यतन करने के लिए की है :
उद्देश्य सी
CGRect contentRect = CGRectZero;
for (UIView *view in self.scrollView.subviews) {
contentRect = CGRectUnion(contentRect, view.frame);
}
self.scrollView.contentSize = contentRect.size;
तीव्र
let contentRect: CGRect = scrollView.subviews.reduce(into: .zero) { rect, view in
rect = rect.union(view.frame)
}
scrollView.contentSize = contentRect.size
UIScrollView इसकी सामग्री की ऊंचाई को स्वचालित रूप से नहीं जानता है। आपको अपने लिए ऊंचाई और चौड़ाई की गणना करनी चाहिए
इसे कुछ इस तरह से करें
CGFloat scrollViewHeight = 0.0f;
for (UIView* view in scrollView.subviews)
{
scrollViewHeight += view.frame.size.height;
}
[scrollView setContentSize:(CGSizeMake(320, scrollViewHeight))];
लेकिन यह केवल तभी काम करता है जब विचार एक दूसरे से नीचे हों। यदि आपके पास एक दूसरे के बगल में एक दृश्य है, तो आपको केवल एक की ऊंचाई को जोड़ना होगा यदि आप नहीं चाहते कि स्कोरर की सामग्री वास्तव में इससे बड़ी हो।
int y = CGRectGetMaxY(((UIView*)[_scrollView.subviews lastObject]).frame); [_scrollView setContentSize:(CGSizeMake(CGRectGetWidth(_scrollView.frame), y))];
सेट translatesAutoresizingMaskIntoConstraints
करने के लिए NO
शामिल सभी दृश्यों पर।
स्थिति और बाहरी स्क्रॉल के साथ अपने स्क्रॉल दृश्य को स्क्रॉल आकार में देखें।
स्क्रॉल दृश्य के भीतर उपविभाजन बिछाने के लिए अवरोधों का उपयोग करें, यह सुनिश्चित करते हुए कि स्क्रॉल स्क्रॉल के चारों किनारों पर बाधाएं बंधी हैं और अपने आकार को प्राप्त करने के लिए स्क्रॉल दृश्य पर निर्भर नहीं हैं।
स्रोत: https://developer.apple.com/library/ios/technotes/tn2154/_index.html
मैंने एस्पुज और जेसीसी के जवाब में इसे जोड़ा। यह सबव्यू की y स्थिति का उपयोग करता है और इसमें स्क्रॉल बार शामिल नहीं हैं। एडिट सबसे कम उप दृश्य के निचले भाग का उपयोग करता है जो दिखाई देता है।
+ (CGFloat) bottomOfLowestContent:(UIView*) view
{
CGFloat lowestPoint = 0.0;
BOOL restoreHorizontal = NO;
BOOL restoreVertical = NO;
if ([view respondsToSelector:@selector(setShowsHorizontalScrollIndicator:)] && [view respondsToSelector:@selector(setShowsVerticalScrollIndicator:)])
{
if ([(UIScrollView*)view showsHorizontalScrollIndicator])
{
restoreHorizontal = YES;
[(UIScrollView*)view setShowsHorizontalScrollIndicator:NO];
}
if ([(UIScrollView*)view showsVerticalScrollIndicator])
{
restoreVertical = YES;
[(UIScrollView*)view setShowsVerticalScrollIndicator:NO];
}
}
for (UIView *subView in view.subviews)
{
if (!subView.hidden)
{
CGFloat maxY = CGRectGetMaxY(subView.frame);
if (maxY > lowestPoint)
{
lowestPoint = maxY;
}
}
}
if ([view respondsToSelector:@selector(setShowsHorizontalScrollIndicator:)] && [view respondsToSelector:@selector(setShowsVerticalScrollIndicator:)])
{
if (restoreHorizontal)
{
[(UIScrollView*)view setShowsHorizontalScrollIndicator:YES];
}
if (restoreVertical)
{
[(UIScrollView*)view setShowsVerticalScrollIndicator:YES];
}
}
return lowestPoint;
}
self.scrollView.showsHorizontalScrollIndicator = NO;
self.scrollView.showsVerticalScrollIndicator = NO;
शुरुआत में और self.scrollView.showsHorizontalScrollIndicator = YES;
self.scrollView.showsVerticalScrollIndicator = YES;
विधि के अंत में ?
यहाँ किसी को भी जो इसे बदलने के लिए बहुत आलसी है स्विफ्ट में स्वीकृत उत्तर दिया गया है :)
var contentRect = CGRectZero
for view in self.scrollView.subviews {
contentRect = CGRectUnion(contentRect, view.frame)
}
self.scrollView.contentSize = contentRect.size
यहां @ लेविटैन के उत्तर का एक स्विफ्ट 3 अनुकूलन है:
विस्तार
import UIKit
extension UIScrollView {
func resizeScrollViewContentSize() {
var contentRect = CGRect.zero
for view in self.subviews {
contentRect = contentRect.union(view.frame)
}
self.contentSize = contentRect.size
}
}
उपयोग
scrollView.resizeScrollViewContentSize()
उपयोग करने के लिए बहुत आसान है!
निम्नलिखित विस्तार स्विफ्ट में सहायक होगा ।
extension UIScrollView{
func setContentViewSize(offset:CGFloat = 0.0) {
// dont show scroll indicators
showsHorizontalScrollIndicator = false
showsVerticalScrollIndicator = false
var maxHeight : CGFloat = 0
for view in subviews {
if view.isHidden {
continue
}
let newHeight = view.frame.origin.y + view.frame.height
if newHeight > maxHeight {
maxHeight = newHeight
}
}
// set content size
contentSize = CGSize(width: contentSize.width, height: maxHeight + offset)
// show scroll indicators
showsHorizontalScrollIndicator = true
showsVerticalScrollIndicator = true
}
}
तर्क दिए गए उत्तरों के साथ समान है। हालाँकि, यह भीतर छिपे हुए विचारों को छोड़ देता है UIScrollView
और गणना को स्क्रॉल संकेतकों को छिपाए जाने के बाद किया जाता है।
इसके अलावा, एक वैकल्पिक फ़ंक्शन पैरामीटर है और आप कार्य करने के लिए पैरामीटर पास करके ऑफ़सेट मान जोड़ सकते हैं।
@Leviathan से महान और सबसे अच्छा समाधान। एफपी (कार्यात्मक प्रोग्रामिंग) दृष्टिकोण का उपयोग कर तेजी से अनुवाद करने के लिए।
self.scrollView.contentSize = self.scrollView.subviews.reduce(CGRect(), {
CGRectUnion($0, $1.frame)
}.size
self.contentSize = self.subviews.reduce(CGRect(), { $0.union($1.frame) }).size
आप UIScrollView के अंदर सामग्री की ऊंचाई की गणना कर सकते हैं कि कौन सा बच्चा "पंखों तक पहुंचता है"। यह गणना करने के लिए आपको मूल Y (प्रारंभ) और आइटम की ऊँचाई को ध्यान में रखना होगा।
float maxHeight = 0;
for (UIView *child in scrollView.subviews) {
float childHeight = child.frame.origin.y + child.frame.size.height;
//if child spans more than current maxHeight then make it a new maxHeight
if (childHeight > maxHeight)
maxHeight = childHeight;
}
//set content size
[scrollView setContentSize:(CGSizeMake(320, maxHeight))];
इस तरह से चीजें करने से आइटम (साक्षात्कार) को सीधे एक दूसरे के नीचे स्टैक नहीं करना पड़ता है।
मैं @ emenegro के समाधान के आधार पर एक और समाधान के साथ आया था
NSInteger maxY = 0;
for (UIView* subview in scrollView.subviews)
{
if (CGRectGetMaxY(subview.frame) > maxY)
{
maxY = CGRectGetMaxY(subview.frame);
}
}
maxY += 10;
[scrollView setContentSize:CGSizeMake(scrollView.frame.size.width, maxY)];
असल में, हम यह पता लगाते हैं कि कौन सा तत्व दृश्य में सबसे नीचे है और नीचे की ओर 10px पैडिंग जोड़ता है
क्योंकि एक स्क्रॉल दृश्य में अन्य स्क्रॉल दृश्य या भिन्न inDepth उप दृश्य पेड़ हो सकते हैं, गहराई से पुनरावर्ती रूप से चलाना बेहतर होता है।
स्विफ्ट 2
extension UIScrollView {
//it will block the mainThread
func recalculateVerticalContentSize_synchronous () {
let unionCalculatedTotalRect = recursiveUnionInDepthFor(self)
self.contentSize = CGRectMake(0, 0, self.frame.width, unionCalculatedTotalRect.height).size;
}
private func recursiveUnionInDepthFor (view: UIView) -> CGRect {
var totalRect = CGRectZero
//calculate recursevly for every subView
for subView in view.subviews {
totalRect = CGRectUnion(totalRect, recursiveUnionInDepthFor(subView))
}
//return the totalCalculated for all in depth subViews.
return CGRectUnion(totalRect, view.frame)
}
}
प्रयोग
scrollView.recalculateVerticalContentSize_synchronous()
या बस करो:
int y = CGRectGetMaxY(((UIView*)[_scrollView.subviews lastObject]).frame); [_scrollView setContentSize:(CGSizeMake(CGRectGetWidth(_scrollView.frame), y))];
(यह समाधान मेरे द्वारा इस पृष्ठ में एक टिप्पणी के रूप में जोड़ा गया था। इस टिप्पणी के लिए 19 अप-वोट प्राप्त करने के बाद, मैंने इस समाधान को समुदाय के लाभ के लिए एक औपचारिक उत्तर के रूप में जोड़ने का फैसला किया है!)
कम करने का उपयोग कर Swift4 के लिए:
self.scrollView.contentSize = self.scrollView.subviews.reduce(CGRect.zero, {
return $0.union($1.frame)
}).size
आकार उसके अंदर भरी हुई सामग्री और कतरन विकल्पों पर निर्भर करता है। यदि इसका एक टेक्स्टव्यू है, तो यह रैपिंग पर भी निर्भर करता है कि टेक्स्ट की कितनी लाइनें, फॉन्ट साइज, और इसी तरह और कई चीजें। आपके लिए खुद की गणना करना लगभग असंभव है। अच्छी खबर यह है, यह देखने और लोड करने के बाद गणना की जाती है। इससे पहले, यह सभी अज्ञात है और सामग्री आकार फ्रेम आकार के समान होगा। लेकिन, viewWillAppear मेथड में और उसके बाद (जैसे viewDidAppear) कंटेंट साइज वास्तविक होगा।
रिची के कोड को रैप करते हुए मैंने एक कस्टम UIScrollView वर्ग बनाया जो पूरी तरह से आकार देने वाली सामग्री को स्वचालित करता है!
SBScrollView.h
@interface SBScrollView : UIScrollView
@end
SBScrollView.m:
@implementation SBScrollView
- (void) layoutSubviews
{
CGFloat scrollViewHeight = 0.0f;
self.showsHorizontalScrollIndicator = NO;
self.showsVerticalScrollIndicator = NO;
for (UIView* view in self.subviews)
{
if (!view.hidden)
{
CGFloat y = view.frame.origin.y;
CGFloat h = view.frame.size.height;
if (y + h > scrollViewHeight)
{
scrollViewHeight = h + y;
}
}
}
self.showsHorizontalScrollIndicator = YES;
self.showsVerticalScrollIndicator = YES;
[self setContentSize:(CGSizeMake(self.frame.size.width, scrollViewHeight))];
}
@end
कैसे उपयोग करें:
बस अपने। नियंत्रक के लिए .h फ़ाइल आयात करें और सामान्य UIScrollView एक के बजाय एक SBScrollView उदाहरण घोषित करें।
डायनामिक कंटेंट का आकार इस तरह सेट करें।
self.scroll_view.contentSize = CGSizeMake(screen_width,CGRectGetMaxY(self.controlname.frame)+20);
मुझे सबसे अच्छा काम करने के लिए लेविथान का जवाब भी मिला। हालांकि, यह एक अजीब ऊंचाई की गणना कर रहा था। जब सबव्यू के माध्यम से लूपिंग किया जाता है, अगर स्क्रॉल संकेतक स्क्रॉल संकेतक दिखाने के लिए सेट किया जाता है, तो वे सबव्यू की सरणी में होंगे। इस मामले में, समाधान लूपिंग से पहले स्क्रॉल संकेतक को अस्थायी रूप से अक्षम करना है, फिर उनकी पिछली दृश्यता सेटिंग को फिर से स्थापित करें।
-(void)adjustContentSizeToFit
UIScrollView के कस्टम उपवर्ग पर एक सार्वजनिक विधि है।
-(void)awakeFromNib {
dispatch_async(dispatch_get_main_queue(), ^{
[self adjustContentSizeToFit];
});
}
-(void)adjustContentSizeToFit {
BOOL showsVerticalScrollIndicator = self.showsVerticalScrollIndicator;
BOOL showsHorizontalScrollIndicator = self.showsHorizontalScrollIndicator;
self.showsVerticalScrollIndicator = NO;
self.showsHorizontalScrollIndicator = NO;
CGRect contentRect = CGRectZero;
for (UIView *view in self.subviews) {
contentRect = CGRectUnion(contentRect, view.frame);
}
self.contentSize = contentRect.size;
self.showsVerticalScrollIndicator = showsVerticalScrollIndicator;
self.showsHorizontalScrollIndicator = showsHorizontalScrollIndicator;
}
मुझे लगता है कि यह UIScrollView के सामग्री दृश्य आकार को अपडेट करने का एक अच्छा तरीका हो सकता है।
extension UIScrollView {
func updateContentViewSize() {
var newHeight: CGFloat = 0
for view in subviews {
let ref = view.frame.origin.y + view.frame.height
if ref > newHeight {
newHeight = ref
}
}
let oldSize = contentSize
let newSize = CGSize(width: oldSize.width, height: newHeight + 20)
contentSize = newSize
}
}
import UIKit
class DynamicSizeScrollView: UIScrollView {
var maxHeight: CGFloat = UIScreen.main.bounds.size.height
var maxWidth: CGFloat = UIScreen.main.bounds.size.width
override func layoutSubviews() {
super.layoutSubviews()
if !__CGSizeEqualToSize(bounds.size,self.intrinsicContentSize){
self.invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
let height = min(contentSize.height, maxHeight)
let width = min(contentSize.height, maxWidth)
return CGSize(width: width, height: height)
}
}
viewDidLayoutSubviews
इसलिए चला रहा था ताकि ऑटोलाययट खत्म हो जाए, iOS7 में यह अच्छी तरह से काम कर रहा था, लेकिन किसी कारणवश ओएस iOS6 का परीक्षण करने से काम खत्म नहीं हुआ, इसलिए मेरे पास कुछ गलत ऊंचाई मूल्य थे, इसलिए मैंनेviewDidAppear
अब ठीक काम किया। बस यह इंगित करने के लिए कि शायद किसी को इसकी आवश्यकता होगी। धन्यवाद