من المتعارف عليه بأن الـ Menu في SwiftUI عباره عن Button ويعامل كـ Button
بما يعني عن الضغط عليه سوف تظهر الخيارات بشكل تلقائي مثال
struct ContentView: View {
var body: some View {
VStack {
Menu {
Button(action: { print("Menu button 1")
}) {
Text("Menu button 1")
}
Button(action: { print("Menu button 2")
}) {
Text("Menu button 2")
}
} label: {
Text("Menu")
}
}
}
}
فيديو يوضح المثال السابق
كما هو واضح في المثال السابق بمجرد الضغط على الزر يتم عرض عناصر الـ Menu بشكل مباشر
لكن في بعض الاوقات تحتاج ان تعرض الخيارات بعد ضغطه مطوله Long press وليس بمجرد الضغط على الـ Menu
لكن قبل شرح هذه النقطه اريد أن اوضح بأن الـ Menu عباره عن Button بتغيير ستايله
Menu {
Button(action: { print("Menu button 1")
}) {
Text("Menu button 1")
}
Button(action: { print("Menu button 2")
}) {
Text("Menu button 2")
}
} label: {
Text("Menu")
}
.buttonStyle(.borderedProminent)
في الكود السابق اضفت buttonStyle الى الـ Menu
النتيجة

كما تلاحظ تم تغيير شكل الزر كما يتم تغييره عند استخدام Button
هذه المعلومة سوف تفدينا لاحقاً
كيف جعل الـ Menu يظهر فقط عند الضغطه المطوله ؟
الطريقة بسيطه وهيا بإستخدام primaryAction
عند اضافة primaryAction الى الـ Menu سوف تستطيع عمل امرين
١- جعل عناصر الـ Menu تظهر بعد ضغطه مطوله
٢- امكانية اضافة action عند الضغط مره وحده مثل الـ Button
Menu {
Button(action: { print("Menu button 1")
}) {
Text("Menu button 1")
}
Button(action: { print("Menu button 2")
}) {
Text("Menu button 2")
}
} label: {
Text("Menu")
} primaryAction: {}
.buttonStyle(.borderedProminent)
لاحظ في الكود السابق لم اضيف اي شي داخل الـ primaryAction
النتيجة
كما تلاحظ عند الضغط على الزر مره وحده لا يحدث اي شي ، وفقط عند الضغط ضغطه مطوله تظهر عناصر الـ Menu
عمل Action عند الضغط على Menu مره وحده
في المثال التالي سوف اغير لون الزر عند الضغط مره وحده
struct ContentView: View {
@State private var changeColor = false
var body: some View {
VStack {
Menu {
Button(action: { print("Menu button 1")
}) {
Text("Menu button 1")
}
Button(action: { print("Menu button 2")
}) {
Text("Menu button 2")
}
} label: {
Text("Menu")
} primaryAction: {
changeColor.toggle()
}
.buttonStyle(.borderedProminent)
.tint(changeColor ? .red : .blue)
}
}
}
النتيجة
كيفية ازالة الـ Highlight من الـ Menu
من الامور الاساسيه عندما تريد اضافة Long press الى الـ Menu بانك لا تريد أن يظهر Highlight الـ Buuton
كما وضحت سابقا عند اضافة primaryAction فانه سوف يعامل معاملة الـ Button عند اول ضغطه وبالتالي سوف يظهر Highlight عند اول ضغطه، لذا يفضل ازالتها
وطريقتها سهله راح نعمل buttonStyle مخصص لازالتها
اضيف الكود التالي الى المشروع
struct NoHighlightButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
}
}
تم استخدمه بهذا الشكل
struct ContentView: View {
var body: some View {
VStack {
Menu {
Button(action: { print("Menu button 1")
}) {
Text("Menu button 1")
}
Button(action: { print("Menu button 2")
}) {
Text("Menu button 2")
}
} label: {
Text("Menu")
} primaryAction: {}
.buttonStyle(NoHighlightButtonStyle())
.foregroundColor(.white)
.padding(.horizontal, 15)
.padding(.vertical, 10)
.background(Color.blue)
.cornerRadius(8)
}
}
}
النتيجة
كما لاحظت في الفيديو السابق تم ازالة في Highlight
واصبح لا يظهر عند الضغط مره واحده على الـ Menu
كيفية تثبت عناصر الـ Menu
هذه الجزئية اضافية بما انه المقال عن الـ Menu
من iOS 16 ، تم اضاف امكانية تثبيت عناصر الـ Menu
عشان تتضح النقطه ، اذا اضفت Menu ضمن الـ List مثلا
في بداية الـ List سوف تظهر الـ Menu بترتيب معين
وعند نهاية الـ List سوف تظهر بترتيب مختلف
مثال للمشكلة اضفت Spacer مره اعلى الـ VStack ومره اسفله ، لاحظت تغيير ترتيب العناصر


الان سوف اقوم بإضافة meunOrder
خارج اقواس الـ Menu
.menuOrder(.fixed)
النتيجة


كما تلاحظ ترتيب العناصر اصبح كما هو في الصورتين
