UILabel sizeToFit ไม่ทำงานกับ autolayout ios6 โดยอัตโนมัติ


152

ฉันควรจะกำหนดค่าโปรแกรม (และวิธีใด) โดยทางโปรแกรม UILabel ซึ่งความสูงขึ้นอยู่กับข้อความ ฉันพยายามตั้งค่าโดยใช้ Storyboard และรหัสร่วมกัน แต่ก็ไม่มีประโยชน์ ทุกคนแนะนำsizeToFitขณะที่การตั้งและlineBreakMode numberOfLinesแต่ไม่ว่าถ้าฉันใส่รหัสที่ในviewDidLoad:, viewDidAppear:หรือviewDidLayoutSubviewsฉันไม่สามารถได้รับมันในการทำงาน ฉันอาจทำให้กล่องเล็กเกินไปสำหรับข้อความยาวและมันจะไม่เติบโตหรือฉันทำให้มันใหญ่เกินไปและจะไม่หดตัว


FWIW รหัสเดียวกัน: ฉันไม่จำเป็นต้องใช้label.sizeToFit()ใน Xcode / viewController ข้อ จำกัด ก็เพียงพอแล้ว ไม่ได้สร้างป้ายในสนามเด็กเล่น จนถึงวิธีเดียวที่ฉันพบว่าการทำงานในสนามเด็กเล่นคือการทำlabel.sizeToFit()
ฮันนี่

คำตอบ:


407

โปรดทราบว่าในกรณีส่วนใหญ่โซลูชันของ Mattทำงานได้ตามที่คาดไว้ แต่ถ้ามันไม่ได้ผลสำหรับคุณโปรดอ่านเพิ่มเติม

ในการทำให้ป้ายกำกับของคุณปรับขนาดความสูงโดยอัตโนมัติคุณต้องทำดังนี้

  1. ตั้งค่าการ จำกัด เลย์เอาต์สำหรับเลเบล
  2. ตั้งข้อจำกัดความสูงด้วยลำดับความสำคัญต่ำ ควรต่ำกว่า ContentCompressionResistancePriority
  3. ตั้งค่า numberOfLines = 0
  4. ตั้งค่า ContentHuggingPriority สูงกว่าระดับความสำคัญของป้ายกำกับ
  5. ตั้งค่าที่ต้องการ MaxLayoutWidth สำหรับป้ายกำกับ ค่าดังกล่าวถูกใช้โดยฉลากเพื่อคำนวณความสูง

ตัวอย่างเช่น:

self.descriptionLabel = [[UILabel alloc] init];
self.descriptionLabel.numberOfLines = 0;
self.descriptionLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.descriptionLabel.preferredMaxLayoutWidth = 200;

[self.descriptionLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
[self.descriptionLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
[self.descriptionLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:self.descriptionLabel];

NSArray* constrs = [NSLayoutConstraint constraintsWithVisualFormat:@"|-8-[descriptionLabel_]-8-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)];
[self addConstraints:constrs];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-8-[descriptionLabel_]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)]];
[self.descriptionLabel addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[descriptionLabel_(220@300)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)]];

ใช้เครื่องมือสร้างอินเตอร์เฟส

  1. ตั้งค่าสี่ข้อ จำกัด ข้อจำกัดความสูงเป็นสิ่งจำเป็น ป้อนคำอธิบายรูปภาพที่นี่

  2. จากนั้นไปที่ตัวตรวจสอบคุณลักษณะของป้ายกำกับและกำหนดจำนวนบรรทัดเป็น 0 ป้อนคำอธิบายรูปภาพที่นี่

  3. ไปที่ตัวตรวจสอบขนาดของฉลากและเพิ่ม ContentHuggingPriority ในแนวตั้งและแนวเนื้อหา ContentCompressionResistancePriority
    ป้อนคำอธิบายรูปภาพที่นี่

  4. เลือกและแก้ไขข้อจำกัดความสูง
    ป้อนคำอธิบายรูปภาพที่นี่

  5. และลดความสำคัญของข้อจำกัดความสูง
    ป้อนคำอธิบายรูปภาพที่นี่

สนุก. :)


4
ใช่! ตรงนี้เป็นคำตอบที่ฉันต้องการ สิ่งเดียวที่ฉันต้องทำคือการตั้งค่าเนื้อหา ฉันทำได้ทุกอย่างใน IB! ขอบคุณมาก.
circuitlego

43
คุณคิดมากเรื่องนี้ ตั้งค่าpreferredMaxLayoutWidthหรือปักความกว้างของฉลาก (หรือด้านขวาและซ้าย) นั่นคือทั้งหมด! จากนั้นจะขยายและหดในแนวตั้งโดยอัตโนมัติเพื่อให้พอดีกับเนื้อหา
matt

ฉันต้องตั้งค่าคุณสมบัติ MaxLayoutWidth ที่ต้องการ + ตรึงความกว้างของป้ายกำกับ ทำงานเหมือนจับใจ :)
MartinMoizard

PreferredMaxLayoutWidth และ / หรือการปักด้านซ้ายและขวาไม่สมบูรณ์ การจัดลำดับความสำคัญของเนื้อหาและการบีบอัดจะทำงานตลอดเวลาหากลำดับความสำคัญของเนื้อหานั้นสูงกว่าข้อ จำกัด อื่น ๆ
Eric Alford

2
^ และในที่สุดฉันก็พบว่าทำไมอาจมีค่าที่จะพูดถึงเมื่อคุณมีเซลล์ติดอยู่ที่ด้านล่างของมุมมองคุณจะต้องกำหนดลำดับความสำคัญของข้อ จำกัด "ถึงด้านล่าง" น้อยกว่า 1,000 ฉันวางไว้ที่ 750 และ ทุกอย่างทำงานได้อย่างสมบูรณ์ ฉันเดาว่ามันจะหดมุมมอง
Mathijs Segers

65

ใน iOS 6 การใช้การชำระอัตโนมัติถ้าด้านข้างของ UILabel (หรือความกว้าง) และด้านบนถูกตรึงไว้มันจะเติบโตและหดในแนวตั้งโดยอัตโนมัติเพื่อให้พอดีกับเนื้อหาโดยไม่มีรหัสเลยและไม่ยุ่งกับความต้านทานการบีบอัดหรืออะไรก็ตาม มันตายง่าย ๆ

preferredMaxLayoutWidthในกรณีที่ซับซ้อนมากขึ้นเพียงแค่ตั้งของฉลาก

ไม่ว่าจะด้วยวิธีใดสิ่งที่ถูกต้องจะเกิดขึ้นโดยอัตโนมัติ


12
คุณต้องตั้งค่า numberOfLines เป็น 0 ไม่เช่นนั้นคุณจะไม่ได้รับการห่อ
devongovett

2
แค่นี้ก็ไม่พอสำหรับฉัน ต้องการจุดที่ 2 จากคำตอบของ @ Mark ด้วย
Danyal Aytekin

เป็นไปได้ไหมที่จะทำให้ฉลากเติบโตโดยอัตโนมัติในหลาย ๆ บรรทัดโดยไม่ต้องเขียนรหัส?
Noor

นี่มันซับซ้อนน้อยกว่าคำตอบที่ยอมรับ ฉันทำสองตัวอย่าง ( ที่นี่และที่นี่ ) แสดงคำตอบนี้
Suragch

@Suragch ใช้ข้อ จำกัด งานนี้ แต่ก็ไม่ได้ทำงานให้กับรหัสเดียวกันในสนามเด็กเล่น ในสนามเด็กเล่นคุณต้องมีlabel.sizeToFit()
ฮันนี่

42

แม้ว่าคำถามจะระบุโดยทางโปรแกรมเมื่อพบปัญหาเดียวกันและชอบที่จะทำงานใน Interface Builder ฉันคิดว่าอาจเป็นประโยชน์ในการเพิ่มคำตอบที่มีอยู่ด้วยโซลูชันตัวสร้างอินเตอร์เฟส

sizeToFitสิ่งแรกคือจะลืม เค้าโครงอัตโนมัติจะจัดการสิ่งนี้ในนามของคุณตามขนาดเนื้อหาที่แท้จริง

ดังนั้นปัญหาคือจะติดฉลากให้พอดีกับเนื้อหาด้วย Auto Layout ได้อย่างไร โดยเฉพาะ - เพราะคำถามกล่าวถึง - ความสูง โปรดทราบว่าใช้หลักการเดียวกันกับความกว้าง

ดังนั้นเรามาเริ่มด้วยตัวอย่าง UILabel ที่ตั้งค่าความสูงเป็น 41px สูง:

ป้อนคำอธิบายรูปภาพที่นี่

อย่างที่คุณเห็นในการคว้าหน้าจอด้านบน"This is my text"มีช่องว่างด้านบนและด้านล่าง นั่นคือช่องว่างระหว่างความสูงของ UILabel และเนื้อหาเนื้อหา

หากเรารันแอพในเครื่องจำลองแน่นอนเราจะเห็นสิ่งเดียวกัน:

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้ให้เลือก UILabel ในเครื่องมือสร้างส่วนต่อประสานและดูการตั้งค่าเริ่มต้นในเครื่องมือตรวจสอบขนาด:

ป้อนคำอธิบายรูปภาพที่นี่

สังเกตข้อ จำกัด ที่ไฮไลต์ไว้ด้านบน นั่นคือความสำคัญกอดเนื้อหา ดังที่ Erica Sadun อธิบายไว้ในการจัดวางเลย์เอาต์อัตโนมัติ iOS ที่ยอดเยี่ยมนี่คือ:

วิธีที่ผู้ชมชอบที่จะหลีกเลี่ยงช่องว่างภายในเพิ่มเติมเป็นเนื้อหาหลัก

สำหรับเราด้วย UILabel เนื้อหาหลักคือข้อความ

ที่นี่เรามาถึงหัวใจของสถานการณ์พื้นฐานนี้ เราได้กำหนดข้อ จำกัด สองประการสำหรับป้ายข้อความ พวกเขาขัดแย้งกัน หนึ่งกล่าวว่า"ความสูงต้องเท่ากับ 41 พิกเซลสูง" อื่น ๆ กล่าวว่า"กอดมุมมองไปที่เนื้อหาของมันดังนั้นเราจึงไม่ได้มีการขยายเพิ่มเติมใด ๆ" ในกรณีของเรากอดมุมมองเป็นข้อความดังนั้นเราจึงไม่มีช่องว่างภายในเพิ่มเติม

ขณะนี้ด้วยเค้าโครงอัตโนมัติด้วยคำแนะนำที่ต่างกันสองคำที่บอกว่าทำสิ่งต่าง ๆ รันไทม์ต้องเลือกอย่างใดอย่างหนึ่ง มันทำทั้งสองอย่างไม่ได้ UILabel ไม่สามารถมีความสูงทั้ง 41 พิกเซลและไม่มีช่องว่างภายใน

วิธีนี้ได้รับการแก้ไขคือการระบุลำดับความสำคัญ คำสั่งหนึ่งจะต้องมีลำดับความสำคัญสูงกว่าอีกคำสั่งหนึ่ง หากทั้งสองคำสั่งพูดต่างกันและมีลำดับความสำคัญเท่ากันข้อยกเว้นจะเกิดขึ้น

งั้นลองไปกันดู ข้อ จำกัด ความสูงของฉันมีความสำคัญของ1000ซึ่งเป็นที่ต้องการ ความสูงกอดเนื้อหาเป็น250ซึ่งเป็นที่อ่อนแอ จะเกิดอะไรขึ้นถ้าเราลดลำดับความสำคัญสูง จำกัด ไป249 ?

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้เราสามารถเห็นความมหัศจรรย์ที่จะเกิดขึ้น มาลองซิมกันดู:

ป้อนคำอธิบายรูปภาพที่นี่

! น่ากลัว รับเนื้อหาได้สำเร็จ เพียงเพราะความสูงมีความสำคัญ249น้อยกว่าเนื้อหากอดความสำคัญ250 โดยทั่วไปฉันพูด"ความสูงฉันระบุที่นี่มีความสำคัญน้อยกว่าสิ่งที่ฉันได้ระบุไว้สำหรับเนื้อหากอด" ดังนั้นการกอดเนื้อหาจะชนะ

บรรทัดล่างการได้รับฉลากเพื่อให้พอดีกับข้อความนั้นทำได้ง่ายเพียงแค่ระบุความสูงหรือความกว้าง - ข้อ จำกัด และการตั้งค่าที่ถูกต้องที่มีลำดับความสำคัญนั้นสอดคล้องกับข้อ จำกัด ลำดับความสำคัญของเนื้อหาของแกนนั้น

จะทำให้ความกว้างเท่ากับการออกกำลังกายสำหรับผู้อ่าน!


3
ขอบคุณมากสำหรับคำอธิบายที่ยอดเยี่ยมของคุณ! ในที่สุดฉันก็เข้าใจลำดับความสำคัญของการกอดเนื้อหา
kernix

คุณช่วยอธิบายเกี่ยวกับลำดับความสำคัญของการบีบอัดเนื้อหาได้หรือไม่ ขอบคุณ!
kernix

2
คำตอบที่ยอดเยี่ยมที่สุด! มีวิธีที่จะ จำกัด จำนวนของบรรทัดที่ทำงานด้วยวิธีนี้หรือไม่?
rafaeljuzo

7

สังเกตเห็นในขนาด IOS7 ไปไม่ได้เหมาะกับการใช้งาน - อาจจะแก้ปัญหาได้เช่นกัน

[textView sizeToFit];
[textView layoutIfNeeded];

1
@Rambatino ใช้ได้กับฉันแล้ว เพิ่มเมื่อคุณต้องการlayoutIfNeeded setNeedsUpdateConstraintsแต่สถานการณ์อาจแตกต่างกันเล็กน้อย
ก.ย.

สิ่งนี้ทำงานได้ดีที่สุดสำหรับฉันเมื่อฉันทำป๊อปโอเวอร์ ฉันต้องทำ layout ถ้าจำเป็นก่อน
Jason

4

ตัวเลือกอื่นสำหรับการตรวจสอบให้แน่ใจ MaxMayLayoutWidth ของฉลากที่ได้รับการซิงค์กับความกว้างของฉลาก:

#import "MyLabel.h"

@implementation MyLabel

-(void)setBounds:(CGRect)bounds
{
    [super setBounds:bounds];

    // This appears to be needed for iOS 6 which doesn't seem to keep
    // label preferredMaxLayoutWidth in sync with its width, which 
    // means the label won't grow vertically to encompass its text if 
    // the label's width constraint changes.
    self.preferredMaxLayoutWidth = self.bounds.size.width;
}

@end

4

ฉันรู้สึกว่าฉันควรมีส่วนร่วมเพราะใช้เวลาพอสมควรในการหาทางแก้ไขที่เหมาะสม:

  • เป้าหมายคือเพื่อให้เค้าโครงอัตโนมัติทำงานโดยไม่ต้องเรียกใช้ sizeToFit () เราจะทำสิ่งนี้โดยการระบุข้อ จำกัด ที่ถูกต้อง:
  • ระบุข้อ จำกัด พื้นที่ด้านบนด้านล่างและส่วนนำ / ต่อท้ายบน UILabel ของคุณ
  • ตั้งค่าจำนวนคุณสมบัติบรรทัดเป็น 0
  • เพิ่มลำดับความสำคัญของการแฮ็กเนื้อหาเป็น 1,000
  • ลดระดับความต้านทานการบีบอัดเนื้อหาให้เหลือ 500
  • บนข้อ จำกัด ด้านล่างของคอนเทนเนอร์ลดระดับความสำคัญเป็น 500

โดยทั่วไปสิ่งที่เกิดขึ้นคือคุณบอก UILabel ของคุณว่าถึงแม้ว่ามันจะมีข้อ จำกัด ความสูงคงที่ แต่ก็สามารถทำลายข้อ จำกัด เพื่อทำให้ตัวเองเล็กลงเพื่อกอดเนื้อหา (ถ้าคุณมีตัวอย่างบรรทัดเดียว) แต่มันไม่สามารถทำได้ ทำลายข้อ จำกัด เพื่อทำให้มีขนาดใหญ่ขึ้น


3

ในกรณีของฉันฉันกำลังสร้างคลาสย่อย UIView ที่มี UILabel (ไม่ทราบความยาว) ใน iOS7 รหัสนั้นตรงไปตรงมา: ตั้งข้อ จำกัด ไม่ต้องกังวลกับการกอดเนื้อหาหรือความต้านทานการบีบอัดและทุกอย่างทำงานตามที่คาดไว้

แต่ใน iOS6 UILabel จะถูกตัดเป็นบรรทัดเดียวเสมอ ไม่มีคำตอบข้างต้นสำหรับฉัน การตั้งค่าการแฮ็กเนื้อหาและความต้านทานการบีบอัดถูกละเว้น วิธีแก้ปัญหาเดียวที่ป้องกันไม่ให้มีการคลิปคือการรวมที่ต้องการ MaxLayoutWidth บนฉลาก แต่ฉันไม่ทราบว่าจะตั้งค่าความกว้างที่ต้องการเนื่องจากขนาดของมุมมองพาเรนต์ไม่เป็นที่รู้จัก (แน่นอนว่าเนื้อหาจะถูกกำหนดด้วย)

ในที่สุดผมก็พบว่าการแก้ปัญหาที่นี่ เนื่องจากฉันทำงานในมุมมองที่กำหนดเองฉันสามารถเพิ่มวิธีการต่อไปนี้เพื่อตั้งค่าความกว้างของเลย์เอาต์ที่ต้องการหลังจากคำนวณข้อ จำกัด หนึ่งครั้งแล้วคำนวณใหม่:

- (void)layoutSubviews
{
    // Autolayout hack required for iOS6
    [super layoutSubviews];
    self.bodyLabel.preferredMaxLayoutWidth = self.bodyLabel.frame.size.width;
    [super layoutSubviews];
}

นี่เป็นสถานการณ์ที่แน่นอนที่ฉันมี ... บางครั้งมันก็ดีที่รู้ว่าคุณไม่ได้อยู่คนเดียว
daveMac

อดัมฉันกำลังดิ้นรนกับสิ่งที่คุณพูดว่าทำงานได้อย่างสมบูรณ์ใน iOS 7 ฉันมีเซลล์ที่กำหนดเองที่มี uiview และ uilabel ฉันสามารถติดฉลากให้พอดีกับเนื้อหา แต่มุมมองไม่ได้ไม่ว่าจะมีข้อ จำกัด อะไรก็ตาม คุณทำงานอย่างไร ฉันสาบานว่าฉันพยายามทุกอย่าง แต่ไม่ได้รับความสูงของฉลาก
denikov

3

ฉันเพิ่มUILabelโปรแกรมและในกรณีของฉันที่เพียงพอ:

label.translatesAutoresizingMaskIntoConstraints = false
label.setContentCompressionResistancePriority(UILayoutPriorityRequired, forAxis: .Vertical)
label.numberOfLines = 0

2

ฉันแก้ไขด้วย xCode6 การวาง "ความกว้างที่ต้องการ" ไปที่อัตโนมัติและตรึงด้านบนป้ายกำกับการนำหน้าและต่อท้าย ป้อนคำอธิบายรูปภาพที่นี่


0
UIFont *customFont = myLabel.font;
CGSize size = [trackerStr sizeWithFont:customFont
                             constrainedToSize:myLabel.frame.size // the size here should be the maximum size you want give to the label
                                 lineBreakMode:UILineBreakModeWordWrap];
float numberOfLines = size.height / customFont.lineHeight;
myLabel.numberOfLines = numberOfLines;
myLabel.frame = CGRectMake(258, 18, 224, (numberOfLines * customFont.lineHeight));

0

ฉันพบปัญหานี้เช่นกันกับคลาสย่อย UIView ที่มี UILabel เป็นหนึ่งถ้าองค์ประกอบภายใน แม้ว่าจะมีการเปิดใช้อัตโนมัติและลองใช้โซลูชันที่แนะนำทั้งหมด แต่ฉลากก็ไม่ได้ทำให้ความสูงของข้อความแน่น ในกรณีของฉันฉันแค่ต้องการให้ป้ายกำกับเป็นหนึ่งบรรทัด

อย่างไรก็ตามสิ่งที่ใช้ได้ผลสำหรับฉันคือการเพิ่มข้อจำกัดความสูงที่จำเป็นสำหรับ UILabel และตั้งค่าด้วยตนเองเป็นความสูงที่ถูกต้องเมื่อเรียกใช้ intrinsicContentSize หากคุณไม่มี UILabel อยู่ใน UIView อื่นคุณสามารถลอง subclassing UILabel และจัดให้มีการใช้งานที่คล้ายกันโดยการตั้งค่าข้อ จำกัด ความสูงก่อนแล้วจึงส่งกลับ
[super instrinsicContentSize]; แทน [self.containerview intrinsiceContentSize]; เช่นฉันทำด้านล่างซึ่งเป็นเฉพาะกับ sublass UIView ของฉัน

- (CGSize)intrinsicContentSize
{
    CGRect expectedTextBounds = [self.titleLabel textRectForBounds:self.titleLabel.bounds limitedToNumberOfLines:1];
    self.titleLabelHeightConstraint.constant = expectedTextBounds.size.height;
    return [self.containerView intrinsicContentSize];

}

ทำงานได้อย่างสมบูรณ์แบบในตอนนี้บน iOS 7 และ iOS 8


เป็นเรื่องน่าสังเกตว่าถ้าคุณตั้งค่ามุมมองของคุณอย่างถูกต้อง (เช่นข้อ จำกัด ของคุณถูกต้องและคุณตั้งค่าทุกอย่างในขั้นตอนที่ถูกต้องในวงจรชีวิตของมุมมอง) คุณไม่ควรต้องแทนที่ intrinsicContentSizeคุณไม่ควรจะต้องแทนที่ รันไทม์ควรจะสามารถคำนวณสิ่งนี้ตามข้อ จำกัด การตั้งค่าของคุณอย่างถูกต้อง
John Rogers

ในทางทฤษฎีแล้วควรจะถูกต้อง แต่เราไม่สามารถเข้าถึง API ส่วนตัวและการใช้งานทั้งหมดของ Apple และพวกเขาจะไม่ผิดพลาดและมีข้อบกพร่องในรหัสของพวกเขา
n8tr

... แต่ [super intrinsicContentSize] ควรดูแลมันเป็นสิ่งที่ฉันพูด หากคุณติดตั้งเลย์เอาต์อัตโนมัติอย่างถูกต้อง
John Rogers

0

ทางออกที่เหมาะกับฉัน; หาก UILabel ของคุณมีความกว้างคงที่ให้เปลี่ยนข้อ จำกัด จากconstant =เป็นconstant <=ในไฟล์อินเตอร์เฟสของคุณ

ป้อนคำอธิบายรูปภาพที่นี่


-1

ในกรณีของฉันเมื่อใช้ป้ายชื่อใน UITableViewCell ป้ายกำกับที่จะปรับขนาด แต่ความสูงจะเกินความสูงของเซลล์ตาราง นี่คือสิ่งที่ได้ผลสำหรับฉัน ฉันทำตาม Max MacLeod แล้วทำให้แน่ใจว่าความสูงของเซลล์ถูกตั้งค่าเป็น UITableViewAutomaticDimension

คุณสามารถเพิ่มสิ่งนี้ได้ใน init หรือ awakeFromNib ของคุณ

self.tableView.rowHeight = UITableViewAutomaticDimension.  

ในกระดานเรื่องราวให้เลือกเซลล์เปิดตัวตรวจสอบขนาดแล้วตรวจสอบให้แน่ใจว่าได้ตั้งค่าความสูงของแถวเป็น "เริ่มต้น" โดยทำเครื่องหมายที่ช่อง 'กำหนดเอง'

มีปัญหาใน 8.0 ที่ต้องกำหนดเป็นรหัสด้วย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.