-
Notifications
You must be signed in to change notification settings - Fork 350
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature] - Support for image resizing inside Markdown text #376
base: main
Are you sure you want to change the base?
Changes from 1 commit
d8e0552
3b4c9e2
b55dd5b
14b521e
47c147a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,11 @@ struct ImageView: View { | |
@Environment(\.imageBaseURL) private var baseURL | ||
|
||
private let data: RawImageData | ||
private let size: MarkdownImageSize? | ||
|
||
init(data: RawImageData) { | ||
init(data: RawImageData, size: MarkdownImageSize? = nil) { | ||
self.data = data | ||
self.size = size | ||
} | ||
|
||
var body: some View { | ||
|
@@ -18,6 +20,7 @@ struct ImageView: View { | |
content: .init(block: self.content) | ||
) | ||
) | ||
.frame(size: size) | ||
} | ||
|
||
private var label: some View { | ||
|
@@ -49,12 +52,16 @@ struct ImageView: View { | |
} | ||
|
||
extension ImageView { | ||
init?(_ inlines: [InlineNode]) { | ||
guard inlines.count == 1, let data = inlines.first?.imageData else { | ||
return nil | ||
init?(_ inlines: [InlineNode]) { | ||
if inlines.count == 2, #available(iOS 16.0, macOS 13.0, tvOS 16.0, *), let data = inlines.first?.imageData, let size = inlines.last?.size { | ||
self.init(data: data, size: size) | ||
} | ||
else if inlines.count == 1, let data = inlines.first?.imageData { | ||
self.init(data: data) | ||
} else { | ||
return nil | ||
} | ||
} | ||
self.init(data: data) | ||
} | ||
} | ||
|
||
extension View { | ||
|
@@ -88,3 +95,29 @@ private struct LinkModifier: ViewModifier { | |
} | ||
} | ||
} | ||
|
||
extension View { | ||
fileprivate func frame(size: MarkdownImageSize?) -> some View { | ||
self.modifier(ImageViewFrameModifier(size: size)) | ||
} | ||
} | ||
|
||
private struct ImageViewFrameModifier: ViewModifier { | ||
let size: MarkdownImageSize? | ||
|
||
func body(content: Content) -> some View { | ||
if let size { | ||
if let width = size.width, let height = size.height { | ||
content.frame(width: width, height: height) | ||
} else if let width = size.width, size.height == nil { | ||
content.frame(width: width) | ||
} else if let height = size.height, size.width == nil { | ||
content.frame(height: height) | ||
} else { | ||
content | ||
} | ||
} else { | ||
content | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're absolutely right. I'm making the change. |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be awesome if it also supported proportional width and height
e.g.
{width=50%}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I thought about it too. Can be quickly achieve for iOS 17+ with the new
containerRelativeFrame
modifier for horizontal configuration.But I'm not sure of what 50% height would mean in the context of a vertical scrolling view. Does it mean 50% of the scrollview content, 50% of the nearest block where the content is, ... Depending on the answer could be harder to implement.
I've draft a commit to demonstrate horizontal relative width handling.
This is a cat with
{width=50%}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't support relative height in the vertically scrollable ScrollView and relative width in the horizontally scrollable ScrollView.
GeometryReader
also "doesn't work" in these cases and returns a size equal to 10, but I think it's fine because these use cases don't make much sense and users of this framework would be also confused about what the 100 % actually is.The
containerRelativeFrame
is cool but unfortunately supported just by iOS 17+, as you mentioned.GeometryReader
could be utilized, so it also supports older iOS.Here is an example of the relative sizes:
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've submitted a new commit using
GeometryReader
to handle relative width size.